{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import datetime\n",
    "from sklearn.svm import SVC,LinearSVC\n",
    "from sklearn.ensemble import RandomForestClassifier,AdaBoostClassifier\n",
    "from sklearn.tree import DecisionTreeClassifier\n",
    "import lightgbm as lgb \n",
    "from sklearn.model_selection import train_test_split,GridSearchCV\n",
    "import tensorflow as tf\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "from sklearn.metrics import accuracy_score,recall_score\n",
    "from sklearn.feature_selection import SelectKBest,SelectPercentile,SelectFromModel,chi2,f_classif,mutual_info_classif,RFE\n",
    "from scipy.stats import pearsonr\n",
    "from sklearn.ensemble import RandomForestRegressor,RandomForestClassifier\n",
    "from sklearn.svm import SVC,LinearSVC,LinearSVR,SVR\n",
    "from sklearn.tree import DecisionTreeClassifier\n",
    "from sklearn.model_selection import train_test_split\n",
    "import gc\n",
    "import pickle\n",
    "import matplotlib.pyplot as plt\n",
    "import time\n",
    "from collections import OrderedDict\n",
    "from keras.layers import Input, Dense, LSTM\n",
    "from keras.models import Model\n",
    "from keras.layers import *\n",
    "from keras.models import *\n",
    "from keras.optimizers import Adam\n",
    "from keras.callbacks import EarlyStopping\n",
    "import keras.backend as K"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "start_date = '2005-05-01'\n",
    "end_date = '2018-05-31'\n",
    "\n",
    "test_start_date = '2018-06-01'\n",
    "test_end_date = '2019-12-28'\n",
    "start_year = start_date[:4]\n",
    "end_year = end_date[:4]\n",
    "\n",
    "select_index = '000300.XSHG'\n",
    "next_n = 3 #data_y延期n月\n",
    "\n",
    "start_quarter = '2015-05'\n",
    "start_month = '2015-05'\n",
    "\n",
    "seq_len = 5 #lstm back num"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "res =  pd.read_csv(\"data/沪深300月度宏观经济数据1.csv\",header=0,index_col=0,sep='\\s+',parse_dates=[1])\n",
    "res_a = pd.read_csv(\"data/沪深300月度宏观经济数据2.csv\",header=0,index_col=0,sep='\\s+',parse_dates=[1])\n",
    "price = pd.read_csv(\"data/沪深300每日交易close价格.csv\",header=0,index_col=0,sep='\\s+',parse_dates=[0])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "res.index = res['stat_month']\n",
    "res_a.index = res_a['stat_month']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_macro_data(ml,sd, ed):\n",
    "    res_ = res.loc[ml[0]:ml[-1]]\n",
    "    res_a_ = res_a.loc[ml[0]:ml[-1]]\n",
    "    price_ = price.loc[sd:ed]\n",
    "    return [res_, res_a_, price_]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_year_list(start_year,end_year):\n",
    "    sy = int(start_year)\n",
    "    ey = int(end_year)\n",
    "    l = []\n",
    "    for i in range(sy,ey+1):\n",
    "        l.append(str(i))\n",
    "    return l"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_quarter_list(start_year,end_year):\n",
    "    sy = int(start_year)\n",
    "    ey = int(end_year)\n",
    "    l = []\n",
    "    for y in range(sy,ey+1):\n",
    "        for q in range(3,13,3):\n",
    "            if q < 10:\n",
    "                s = str(y) + '-' + '0' + str(q)\n",
    "                l.append(s)\n",
    "            else:\n",
    "                s = str(y) + '-' +  str(q)\n",
    "                l.append(s)\n",
    "    return l"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_month_list(start_date,end_date):\n",
    "    sy = int(start_date[:4])\n",
    "    ey = int(end_date[:4])\n",
    "    sm = int(start_date[5:7])\n",
    "    em = int(end_date[5:7])\n",
    "    l = []\n",
    "    for y in range(sy,ey+1):\n",
    "        if y == sy:\n",
    "            for i in range(sm,13):\n",
    "                if i< 10:\n",
    "                    s = str(y) + '-' + '0' + str(i)\n",
    "                    l.append(s)\n",
    "                else:\n",
    "                    s = str(y) + '-' +  str(i)      \n",
    "                    l.append(s)\n",
    "               \n",
    "        elif y == ey:\n",
    "            for i in range(1,em+1):\n",
    "                if i < 10:\n",
    "                    s = str(y) + '-' + '0' + str(i)\n",
    "                    l.append(s)\n",
    "                else:\n",
    "                    s = str(y) + '-' +  str(i)\n",
    "                    l.append(s)\n",
    "        else:           \n",
    "            for i in range(1,13):\n",
    "                if i < 10:\n",
    "                    s = str(y) + '-' + '0' + str(i)\n",
    "                    l.append(s)\n",
    "                else:\n",
    "                    s = str(y) + '-' +  str(i)\n",
    "                    l.append(s)\n",
    "    return l"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "#获取月度价格数据\n",
    "def get_price_month_data(price_day,n='mean',mean_num=1):\n",
    "    '''\n",
    "    :param price: 输入价格数据，index为datetime类型\n",
    "    :param type: 计算方式，’mean‘取月平均值，若为int,则从第几个交易日开始计算均值，长度为mean_num，\n",
    "    :param mean_num: 计算均值的长度\n",
    "    :return:\n",
    "    '''\n",
    "    ind = list(price_day.index)\n",
    "    s_ind = [datetime.datetime.strftime(i, '%Y%m%d') for i in ind]\n",
    "    price_day.index = s_ind\n",
    "    num_ind = [int(i) for i in s_ind]\n",
    "    cut_ind = [int(i / 100) for i in num_ind]\n",
    "    cut_s_ind = [(str(i)[:4] + '-' + str(i)[4:]) for i in cut_ind]\n",
    "    price_day['stat_date'] = cut_s_ind\n",
    "    if n == 'mean':\n",
    "        res = price_day.groupby(by=['stat_date']).mean()\n",
    "    else:\n",
    "        ind_sig = list(set(price['stat_date'].values))\n",
    "        index_list = []\n",
    "        mean_list = []\n",
    "        for ind in ind_sig:\n",
    "            df = price[price['stat_date']==ind]\n",
    "            sel_df = df.iloc[n-1:n+mean_num-1,0]\n",
    "            index = list(sel_df.index)\n",
    "            if len(index) == 0:\n",
    "                continue\n",
    "            index = index[0]\n",
    "            index_list.append(index)\n",
    "            mean_df = sel_df.mean()\n",
    "            mean_list.append(mean_df)\n",
    "        res_df = pd.DataFrame(mean_list,index=index_list,columns=['month_price'])\n",
    "        res = res_df.sort_index()\n",
    "        res_index = list(res.index)\n",
    "        ind_s_cut = [i[:4] + '-' + i[4:6] for i in res_index]\n",
    "        res.index = ind_s_cut\n",
    "    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_pure_values(data):\n",
    "    '''\n",
    "    获取纯净数值，将DataFrame中的非数值项剔除，例如‘code’项（str）\n",
    "    input:\n",
    "    data:pd.DataFrame,index为股票代码\n",
    "    putput:\n",
    "    DataFrame：只含数值项\n",
    "    '''\n",
    "    columns = list(data.columns)\n",
    "    for column in columns:\n",
    "        if not(isinstance(data[column][0],int) or isinstance(data[column][0],float)):\n",
    "            data = data.drop([column],axis=1)\n",
    "    return data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "def winsorize_and_standarlize(data, qrange=[0.05, 0.95], axis=0):\n",
    "    if isinstance(data, pd.DataFrame):\n",
    "        if axis == 0:\n",
    "            q_down = data.quantile(qrange[0])\n",
    "            q_up = data.quantile(qrange[1])\n",
    "            col = data.columns\n",
    "            for n in col:\n",
    "                data[n][data[n] > q_up[n]] = q_up[n]\n",
    "                data[n][data[n] < q_down[n]] = q_down[n]\n",
    "            data = (data - data.mean()) / data.std()\n",
    "            data = data.fillna(0)\n",
    "        else:\n",
    "            data = data.stack()\n",
    "            data = data.unstack(0)\n",
    "            q_down = data.quantile(qrange[0])\n",
    "            q_up = data.quantile(qrange[1])\n",
    "            col = data.columns\n",
    "            for n in col:\n",
    "                data[n][data[n] > q_up[n]] = q_up[n]\n",
    "                data[n][data[n] < q_down[n]] = q_down[n]\n",
    "            data = (data - data.mean()) / data.std()\n",
    "            data = data.stack().unstack(0)\n",
    "            data = data.fillna(0)\n",
    "\n",
    "    elif isinstance(data, pd.Series):\n",
    "        q_down = data.quantile(qrange[0])\n",
    "        q_up = data.quantile(qrange[1])\n",
    "        data[data > q_up] = q_up\n",
    "        data[data < q_down] = q_down\n",
    "        data = (data - data.mean()) / data.std()\n",
    "    return data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_profit_class(data):\n",
    "    '''\n",
    "    对数据进行分类标记\n",
    "    '''\n",
    "    data_diff = data.diff(next_n)\n",
    "    data_diff[data_diff > 0] = 1\n",
    "    data_diff[data_diff < 0] = 0\n",
    "    #data_diff[data_diff == 2] = -1\n",
    "    #data_diff[data_diff == -2] = 1\n",
    "    return data_diff\n",
    "\n",
    "def get_final_data(input_x,input_y):\n",
    "    input_y = input_y.shift(-next_n).to_frame().fillna(method='ffill')\n",
    "    data_m = pd.merge(input_x,input_y,left_index=True,right_index=True,how='right')\n",
    "    columns_m = data_m.columns\n",
    "    data_x = data_m[columns_m[:-1]]\n",
    "    data_y = data_m[columns_m[-1]]\n",
    "    return data_x,data_y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "class FeatureSelection():\n",
    "    '''\n",
    "    特征选择：\n",
    "    identify_collinear：基于相关系数，删除小于correlation_threshold的特征\n",
    "    identify_importance_lgbm：基于LightGBM算法，得到feature_importance,选择和大于p_importance的特征\n",
    "    filter_select:单变量选择，指定k,selectKBest基于method提供的算法选择前k个特征，selectPercentile选择前p百分百的特征\n",
    "    wrapper_select:RFE，基于estimator递归特征消除，保留n_feature_to_select个特征\n",
    "    '''\n",
    "    def __init__(self):\n",
    "        self.filter_supports = None #bool型，特征是否被选中\n",
    "        self.wrapper_supports = None\n",
    "        self.embedded_supports = None\n",
    "        self.lgbm_columns = None  #选择的特征\n",
    "        self.filter_columns = None\n",
    "        self.wrapper_columns = None\n",
    "        self.embedded_columns = None\n",
    "        self.record_collinear = None #自相关矩阵大于门限值\n",
    "        \n",
    "    def identify_collinear(self, data, correlation_threshold):\n",
    "\n",
    "        columns = data.columns\n",
    "        self.correlation_threshold = correlation_threshold\n",
    "\n",
    "        # Calculate the correlations between every column\n",
    "        corr_matrix = data.corr()\n",
    "        \n",
    "        self.corr_matrix = corr_matrix\n",
    "    \n",
    "        # Extract the upper triangle of the correlation matrix\n",
    "        upper = corr_matrix.where(np.triu(np.ones(corr_matrix.shape), k = 1).astype(np.bool))\n",
    "        # Select the features with correlations above the threshold\n",
    "        # Need to use the absolute value\n",
    "        to_drop = [column for column in upper.columns if any(upper[column].abs() > correlation_threshold)]\n",
    "        obtain_columns = [column for column in columns if column not in to_drop]\n",
    "        self.columns = obtain_columns\n",
    "        # Dataframe to hold correlated pairs\n",
    "        record_collinear = pd.DataFrame(columns = ['drop_feature', 'corr_feature', 'corr_value'])\n",
    "\n",
    "        # Iterate through the columns to drop\n",
    "        for column in to_drop:\n",
    "\n",
    "            # Find the correlated features\n",
    "            corr_features = list(upper.index[upper[column].abs() > correlation_threshold])\n",
    "\n",
    "            # Find the correlated values\n",
    "            corr_values = list(upper[column][upper[column].abs() > correlation_threshold])\n",
    "            drop_features = [column for _ in range(len(corr_features))]    \n",
    "\n",
    "            # Record the information (need a temp df for now)\n",
    "            temp_df = pd.DataFrame.from_dict({'drop_feature': drop_features,\n",
    "                                             'corr_feature': corr_features,\n",
    "                                             'corr_value': corr_values})\n",
    "\n",
    "            # Add to dataframe\n",
    "            record_collinear = record_collinear.append(temp_df, ignore_index = True)\n",
    "\n",
    "        self.record_collinear = record_collinear\n",
    "        return data[obtain_columns]\n",
    "     \n",
    "        \n",
    "    def identify_importance_lgbm(self, features, labels,p_importance=0.8, eval_metric='auc', task='classification', \n",
    "                                 n_iterations=10, early_stopping = True):\n",
    "        \n",
    "        # One hot encoding\n",
    "        data = features\n",
    "        features = pd.get_dummies(features)\n",
    "\n",
    "        # Extract feature names\n",
    "        feature_names = list(features.columns)\n",
    "\n",
    "        # Convert to np array\n",
    "        features = np.array(features)\n",
    "        labels = np.array(labels).reshape((-1, ))\n",
    "\n",
    "        # Empty array for feature importances\n",
    "        feature_importance_values = np.zeros(len(feature_names))\n",
    "        \n",
    "        #print('Training Gradient Boosting Model\\n')\n",
    "        \n",
    "        # Iterate through each fold\n",
    "        for _ in range(n_iterations):\n",
    "\n",
    "            if task == 'classification':\n",
    "                model = lgb.LGBMClassifier(n_estimators=100, learning_rate = 0.05, verbose = 1)\n",
    "\n",
    "            elif task == 'regression':\n",
    "                model = lgb.LGBMRegressor(n_estimators=100, learning_rate = 0.05, verbose = 1)\n",
    "\n",
    "            else:\n",
    "                raise ValueError('Task must be either \"classification\" or \"regression\"')\n",
    "                \n",
    "            # If training using early stopping need a validation set\n",
    "            if early_stopping:\n",
    "                \n",
    "                train_features, valid_features, train_labels, valid_labels = train_test_split(features, labels, test_size = 0.15)\n",
    "\n",
    "                # Train the model with early stopping\n",
    "                model.fit(train_features, train_labels, eval_metric = eval_metric,\n",
    "                          eval_set = [(valid_features, valid_labels)],\n",
    "                           verbose = -1)\n",
    "                \n",
    "                # Clean up memory\n",
    "                gc.enable()\n",
    "                del train_features, train_labels, valid_features, valid_labels\n",
    "                gc.collect()\n",
    "                \n",
    "            else:\n",
    "                model.fit(features, labels)\n",
    "\n",
    "            # Record the feature importances\n",
    "            feature_importance_values += model.feature_importances_ / n_iterations\n",
    "\n",
    "        feature_importances = pd.DataFrame({'feature': feature_names, 'importance': feature_importance_values})\n",
    "\n",
    "        # Sort features according to importance\n",
    "        feature_importances = feature_importances.sort_values('importance', ascending = False).reset_index(drop = True)\n",
    "\n",
    "        # Normalize the feature importances to add up to one\n",
    "        feature_importances['normalized_importance'] = feature_importances['importance'] / feature_importances['importance'].sum()\n",
    "        feature_importances['cumulative_importance'] = np.cumsum(feature_importances['normalized_importance'])\n",
    "        select_df = feature_importances[feature_importances['cumulative_importance']<=p_importance]\n",
    "        select_columns = select_df['feature']\n",
    "        self.lgbm_columns = list(select_columns.values)\n",
    "        res = data[self.columns]\n",
    "        return res\n",
    "        \n",
    "    def filter_select(self, data_x, data_y, k=None, p=50,method=f_classif):\n",
    "        columns = data_x.columns\n",
    "        if k != None:\n",
    "            model = SelectKBest(method,k)\n",
    "            res = model.fit_transform(data_x,data_y)\n",
    "            supports = model.get_support()\n",
    "        else:\n",
    "            model = SelectPercentile(method,p)\n",
    "            res = model.fit_transform(data_x,data_y)\n",
    "            supports = model.get_support()\n",
    "        self.filter_support_ = supports\n",
    "        self.filter_columns = columns[supports]\n",
    "        return res\n",
    "    \n",
    "    def wrapper_select(self,data_x,data_y,n,estimator):\n",
    "        columns = data_x.columns\n",
    "        model = RFE(estimator=estimator,n_features_to_select=n)\n",
    "        res = model.fit_transform(data_x,data_y)\n",
    "        supports = model.get_support() #标识被选择的特征在原数据中的位置\n",
    "        self.wrapper_supports = supports\n",
    "        self.wrapper_columns = columns[supports]\n",
    "        return res\n",
    "    \n",
    "    def embedded_select(self,data_x,data_y,estimator,threshold=None):\n",
    "        columns = data_x.columns\n",
    "        model = SelectFromModel(estimator=estimator,prefit=False,threshold=threshold)\n",
    "        res = model.fit_transform(data_x,data_y)\n",
    "        supports = model.get_support()\n",
    "        self.embedded_supports = supports\n",
    "        self.embedded_columns = columns[supports]\n",
    "        print(\"self.embedded_columns:\",self.embedded_columns)\n",
    "        return res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "#调参时计算召回率和准确率\n",
    "def lstm_recall(prediction,y,n=1,thr=0.5):\n",
    "    len_p = len(prediction)\n",
    "    l = 0\n",
    "    z = 0\n",
    "    res = []\n",
    "    if n == 1:\n",
    "        for i in range(len_p):\n",
    "            if (prediction[i]>= thr):\n",
    "                l = l+1\n",
    "                if (y[i] ==1):\n",
    "                    z = z+1\n",
    "    elif n==0:\n",
    "         for i in range(len_p):\n",
    "            if (prediction[i]<=thr):\n",
    "                l = l+1\n",
    "                if (y[i] ==0):\n",
    "                    z = z+1\n",
    "    lstm_recall = z/l\n",
    "    return lstm_recall\n",
    "\n",
    "def lstm_accuracy(prediction,y,thr=0.5):\n",
    "    len_p = len(prediction)\n",
    "    l = 0\n",
    "    for i in range(len_p):\n",
    "        if ((prediction[i]>=thr) & (y[i] ==1)) |  ((prediction[i]<thr) & (y[i] ==0)):\n",
    "            l = l + 1\n",
    "            \n",
    "    accuracy = l/len_p\n",
    "    return accuracy"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "def res_output(res,buy_thr=1.6,sell_thr=1.2):\n",
    "    '''\n",
    "    基于lgbm和embedded两组特征选择数据的计算结果确定预测结果\n",
    "    buy_thr:预测股价上升的门限值，默认1.6,\n",
    "    sell_thr:预测股价下降的门限值，默认1.2\n",
    "    大于买入门限标记为1，小于卖出门限标记为-1，中间值认为买入卖出信号不强，选择观望或空仓，卖出信号可用于做空，在无法做空时认为空仓\n",
    "    \n",
    "    '''\n",
    "    length = len(res)\n",
    "    l = []\n",
    "    for i in range(length):\n",
    "        if res[i] > buy_thr:\n",
    "            l.append(1)\n",
    "        elif res[i] < sell_thr:\n",
    "            l.append(-1)\n",
    "        else:\n",
    "            l.append(0)\n",
    "    return l\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "def LSTM_fun_keras(n_input,train_x,train_y,predict_x,prediction_y,seq_len=5):\n",
    "    K.get_session().close()\n",
    "    K.set_session(tf.Session())\n",
    "    K.get_session().run(tf.global_variables_initializer())\n",
    "    INPUT_DIM = n_input\n",
    "    output_dim = 1\n",
    "    batch_size = 8 #每轮训练模型时，样本的数量\n",
    "    epochs = 100 #训练100轮次\n",
    "    hidden_size = 128\n",
    "    lstm_units = 64\n",
    "    inputs = Input(shape=(seq_len, INPUT_DIM))\n",
    "    #drop1 = Dropout(0.3)(inputs)\n",
    "    x = Conv1D(filters = 64, kernel_size = 1, activation = 'relu')(inputs)  #, padding = 'same'\n",
    "    #x = Conv1D(filters=128, kernel_size=5, activation='relu')(output1)#embedded_sequences\n",
    "    x = MaxPooling1D(pool_size = seq_len)(x)\n",
    "    #x = Dropout(0.1)(x)\n",
    "    #print(x.shape)\n",
    "    lstm_out = Bidirectional(LSTM(lstm_units, activation='relu'), name='bilstm')(x)\n",
    "    #lstm_out = LSTM(lstm_units,activation='relu')(x)\n",
    "    #print(lstm_out.shape)\n",
    "    # ATTENTION PART STARTS HERE\n",
    "    attention_probs = Dense(128, activation='sigmoid', name='attention_vec')(lstm_out)\n",
    "    #attention_mul=layers.merge([stm_out,attention_probs], output_shape],mode='concat',concat_axis=1))\n",
    "    attention_mul =Multiply()([lstm_out, attention_probs])\n",
    "    #attention_mul = merge([lstm_out, attention_probs],output_shape=32, name='attention_mul', mode='mul')\n",
    "    #h1 = Dense(hidden_size, activation='relu')(attention_mul)\n",
    "    output_class = Dense(1, activation='sigmoid')(attention_mul)\n",
    "    #output = Dense(10, activation='sigmoid')(drop2)\n",
    "\n",
    "    model_class = Model(inputs=inputs, outputs=output_class)\n",
    "    #print(model_class.summary())\n",
    "    model_class.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])\n",
    "    #model_class.compile(optimizer='rmsprop',loss='binary_crossentropy',metrics=['accuracy'])\n",
    "    # simple early stopping\n",
    "    es = EarlyStopping(monitor='val_loss', mode='min', verbose=1, patience=5)\n",
    "    # fit model\n",
    "    history_class = model_class.fit(train_x, train_y,validation_split=0.2, epochs=epochs, batch_size=1, shuffle=False, callbacks=[es])\n",
    "    #history_class = model_class.fit(train_x, train_y, epochs=epochs, batch_size=batch_size, shuffle=False)\n",
    "    y_pred_class = model_class.predict(predict_x)\n",
    "    print(\"accuracy:\",lstm_accuracy(y_pred_class,prediction_y,thr=0.5))\n",
    "    return y_pred_class"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [],
   "source": [
    "def LSTM_fun(n_input,train_x,train_y,predict_x,prediction_y,seq_len=5):\n",
    "    #LSTM\n",
    "    lr=0.001\n",
    "    lstm_size = 16  #lstm cell数量，基于数据量调整\n",
    "    epoch_num = 10  #打印次数，和n_batch相乘便是迭代次数\n",
    "    n_batch = 200\n",
    "    lookback = seq_len\n",
    "    tf.reset_default_graph()\n",
    "\n",
    "\n",
    "    x = tf.placeholder(tf.float32,[None,lookback,n_input])\n",
    "    y = tf.placeholder(tf.float32,[None,1])\n",
    "\n",
    "    weights = tf.Variable(tf.truncated_normal([lstm_size,1],stddev=0.1))\n",
    "    biases = tf.Variable(tf.constant(0.1,shape=[1]))\n",
    "\n",
    "    def LSTM_net(x,weights,biases):\n",
    "        lstm_cell = tf.contrib.rnn.LSTMCell(lstm_size,name='basic_lstm_cell') #.BasicLSTMCell(lstm_size)\n",
    "        output,final_state = tf.nn.dynamic_rnn(lstm_cell,x,dtype=tf.float32)\n",
    "        results = tf.nn.sigmoid(tf.matmul(final_state[1],weights)+biases)\n",
    "        return results\n",
    "\n",
    "    prediction = LSTM_net(x,weights,biases)\n",
    "\n",
    "    loss = tf.reduce_mean(tf.square(y - prediction))\n",
    "\n",
    "    #train_step = tf.train.GradientDescentOptimizer(lr).minimize(loss)\n",
    "    train_step = tf.train.AdamOptimizer(lr).minimize(loss)\n",
    "\n",
    "    init = tf.global_variables_initializer()\n",
    "    with tf.Session() as sess:\n",
    "        sess.run(init)\n",
    "        for i in range(epoch_num):\n",
    "            for j in range(n_batch):\n",
    "                sess.run(train_step,feed_dict={x:train_x,y:train_y})\n",
    "                train_loss = sess.run(loss,feed_dict={x:train_x,y:train_y})\n",
    "            print('train loss is'+ str(train_loss))\n",
    "        prediction_res = sess.run(prediction,feed_dict={x:predict_x})\n",
    "    print(\"accuracy:\",lstm_accuracy(prediction_res,prediction_y,thr=0.5))\n",
    "    return prediction_res\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_test_time_list(start_date,test_start_date,test_end_date):\n",
    "    '''\n",
    "    使用机器学习算法计算时的时间数据\n",
    "    input:\n",
    "    start_date:取宏观数据的开始时间\n",
    "    test_start_date:预测的开始时间，也就是取宏观数据的截止时间\n",
    "    test_end_date:预测的截止时间，对期间的每一个月都要预测，每一个月都要重跑一遍预测函数，每个月的开始使用上个月28号的价格数据作为截止价格时间\n",
    "    output:\n",
    "    m_l：每一次预测时的月份列表，在此列表内跑预测函数，\n",
    "    start_date,取宏观数据和价格数据的开始时间，由全局变量定义\n",
    "    ed:取价格数据截止时间列表，顺序和m_l对应\n",
    "    '''\n",
    "    test_month = get_month_list(test_start_date,test_end_date)\n",
    "    m_l_pre = []\n",
    "    ed = []\n",
    "    for m in test_month:\n",
    "        ml = get_month_list(start_date,m)\n",
    "        m_l_pre.append(ml)\n",
    "        if m == test_month[-1]:\n",
    "            ed.append(test_end_date)\n",
    "        else:\n",
    "            ed.append(m+'-'+'28')\n",
    "    return m_l_pre,start_date,ed"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "ml_test,sd_test,ed_test = get_test_time_list(start_date,test_start_date,test_end_date)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "def monthly_fun(month_list, start_date, end_date):\n",
    "    macro_data_o = get_macro_data(month_list,start_date, end_date)\n",
    "    res = macro_data_o[0]\n",
    "    res_a = macro_data_o[1]\n",
    "    price = macro_data_o[2]\n",
    "    price_month = get_price_month_data(price)\n",
    "    res.index = res['stat_month']\n",
    "    res_a.index = res['stat_month']\n",
    "\n",
    "    sel_data = pd.merge(res_a, price_month, left_index=True, right_index=True).dropna()  # 使用全部宏观数据\n",
    "    data_pure = get_pure_values(sel_data)\n",
    "    columns = data_pure.columns\n",
    "    data_x_start = data_pure[columns[:-1]]\n",
    "    data_y_o = data_pure[columns[-1]]\n",
    "    data_x_o = winsorize_and_standarlize(data_x_start)\n",
    "    data_y_class_o = get_profit_class(data_y_o)\n",
    "    data_x, data_y_class = get_final_data(data_x_o, data_y_class_o)\n",
    "    _, data_y = get_final_data(data_x_o, data_y_o)\n",
    "    # 特征选择\n",
    "    #print(\"特征选择\")\n",
    "    f = FeatureSelection()\n",
    "    #print(\"去除一些共线性特征\")\n",
    "    n_collinear = f.identify_collinear(data_x, correlation_threshold=0.9) #去除一些共线性特征\n",
    "    #print(\"lightgbm 重要特征\")\n",
    "    lgbm_res = f.identify_importance_lgbm(n_collinear, data_y_class, p_importance=0.9)\n",
    "\n",
    "    #estimator = LinearSVC()\n",
    "    #wrapper_res = f.wrapper_select(data_x=n_collinear, data_y=data_y_class, n=5, estimator=estimator)\n",
    "\n",
    "    #est = LinearSVC(C=0.01, penalty='l1', dual=False)\n",
    "    #print(\"random forest 重要特征\")\n",
    "    est1 = RandomForestClassifier(verbose=1)\n",
    "    embedded_res = f.embedded_select(data_x=n_collinear, data_y=data_y_class, estimator=est1)\n",
    "    # LSTM数据准备\n",
    "    #print(\"数据准备\")\n",
    "    lgbm_n_input = len(lgbm_res.columns)\n",
    "    print(\"lgbm_res.columns:\",lgbm_res.columns)\n",
    "    lgbm_x_a = np.array(lgbm_res)\n",
    "    lgbm_x_o = [lgbm_x_a[i: i + seq_len, :] for i in range(lgbm_res.shape[0] - seq_len)]\n",
    "    lgbm_x_l = len(lgbm_x_o)\n",
    "    lgbm_x_array = np.reshape(lgbm_x_o, [lgbm_x_l, seq_len, lgbm_n_input])\n",
    "    lgbm_x = lgbm_x_array[:-next_n]\n",
    "    lgbm_x_prediction = lgbm_x_array[-next_n:]\n",
    "    lgbm_y_o = np.array([data_y_class[i + seq_len] for i in range(len(data_y_class) - seq_len)])\n",
    "    lgbm_y_array = np.reshape(lgbm_y_o, [lgbm_y_o.shape[0], 1])\n",
    "    lgbm_y = lgbm_y_array[:-next_n]\n",
    "    lgbm_y_prediction = lgbm_y_array[-next_n:]\n",
    "    # print(len(lgbm_y))\n",
    "\n",
    "    embedded_n_input = np.shape(embedded_res)[1]\n",
    "    embedded_x_a = np.array(embedded_res)\n",
    "    embedded_x_o = [embedded_x_a[i: i + seq_len, :] for i in range(embedded_res.shape[0] - seq_len)]\n",
    "    embedded_x_l = len(embedded_x_o)\n",
    "    embedded_x_array = np.reshape(embedded_x_o, [embedded_x_l, seq_len, embedded_n_input])\n",
    "    embedded_x = embedded_x_array[:-next_n]\n",
    "    embedded_x_predition = embedded_x_array[-next_n:]\n",
    "    embedded_y_o = np.array([data_y_class[i + seq_len] for i in range(len(data_y_class) - seq_len)])\n",
    "    embedded_y_array = np.reshape(embedded_y_o, [embedded_y_o.shape[0], 1])\n",
    "    embedded_y = embedded_y_array[:-next_n]\n",
    "\n",
    "    # 获取训练数据和测试数据\n",
    "    # lgbm_train_x,lgbm_test_x,lgbm_train_y,lgbm_test_y = train_test_split(lgbm_x,lgbm_y,test_size=0.3,random_state=0)\n",
    "    # embedded_train_x,embedded_test_x,embedded_train_y,embedded_test_y = train_test_split(embedded_x,embedded_y,test_size=0.3,random_state=0)\n",
    "    #print(\"lightgbm 特征训练lstm\")\n",
    "    lgbm_pre_res = LSTM_fun_keras(lgbm_n_input, lgbm_x, lgbm_y, lgbm_x_prediction, lgbm_y_prediction,seq_len=seq_len)\n",
    "    print(\"lgbm_pre_res: \",lgbm_pre_res)\n",
    "    #print(\"random forest 特征训练lstm\")\n",
    "    embedded_pre_res = LSTM_fun_keras(embedded_n_input, embedded_x, embedded_y, embedded_x_predition, lgbm_y_prediction,seq_len=seq_len)\n",
    "    print(\"embedded_pre_res: \",embedded_pre_res)\n",
    "    # print(lgbm_pre_res)\n",
    "    # print(embedded_pre_res)\n",
    "    pre_res = lgbm_pre_res + embedded_pre_res  # 将两组数据的的预测结果相加\n",
    "    #signal = res_output(pre_res)\n",
    "    # print(signal)\n",
    "    print(\"predict result:\", pre_res)\n",
    "    return pre_res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_pre_signal(ml,sd,ed):\n",
    "    '''\n",
    "    在时间序列下计算最后三个月的预测值，以此作为决策信号\n",
    "    '''\n",
    "    start_clock = time.clock()\n",
    "    length = len(ml)\n",
    "    l = []\n",
    "    for i in range(length):\n",
    "        month_l = ml[i]\n",
    "        end_d = ed[i]\n",
    "        print(\"predict month:\",end_d)\n",
    "        pre = monthly_fun(month_l,sd,end_d)\n",
    "        l.append(pre)\n",
    "    end_clock = time.clock()\n",
    "    clofk_diff = (end_clock - start_clock)/60\n",
    "    print('time cost:%0.3f'%clofk_diff)\n",
    "    return l\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "predict month: 2018-06-28\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.\n",
      "[Parallel(n_jobs=1)]: Done  10 out of  10 | elapsed:    0.0s finished\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "self.embedded_columns: Index(['retail_sin', 'retail_sin_yoy', 'invest_yoy', 'num_acc_yoy',\n",
      "       'early_warning_idx', 'lagging_idx', 'enterprise_value_acc_diff',\n",
      "       'loss_enterprise_ratio_acc', 'current_asset_ratio_acc',\n",
      "       'finished_product_ratio_acc', 'main_business_tax_value_acc'],\n",
      "      dtype='object')\n",
      "lgbm_res.columns: Index(['retail_sin', 'retail_sin_yoy', 'invest', 'invest_yoy', 'primary_yoy',\n",
      "       'centre_project_yoy', 'num_acc_yoy', 'early_warning_idx', 'lagging_idx',\n",
      "       'pmi', 'growth_yoy', 'growth_acc_diff', 'enterprise_value_acc_diff',\n",
      "       'loss_enterprise_ratio_acc_diff', 'total_interest_ratio_acc_diff', 'id',\n",
      "       'enterprise_value_acc', 'loss_enterprise_value_acc',\n",
      "       'loss_enterprise_ratio_acc', 'current_asset_ratio_acc',\n",
      "       'finished_product_ratio_acc', 'main_business_tax_value_acc',\n",
      "       'main_business_tax_ratio_acc', 'financial_expense_ratio_acc',\n",
      "       'total_interest_ratio_acc', 'enterprise_total_loss_ratio_acc',\n",
      "       'vat_ratio_acc'],\n",
      "      dtype='object')\n",
      "Train on 114 samples, validate on 29 samples\n",
      "Epoch 1/100\n",
      "114/114 [==============================] - 2s 16ms/step - loss: 0.7460 - acc: 0.5000 - val_loss: 0.6734 - val_acc: 0.7586\n",
      "Epoch 2/100\n",
      "114/114 [==============================] - 0s 3ms/step - loss: 0.6538 - acc: 0.6316 - val_loss: 0.7033 - val_acc: 0.4828\n",
      "Epoch 3/100\n",
      "114/114 [==============================] - 0s 3ms/step - loss: 0.5455 - acc: 0.7544 - val_loss: 0.7756 - val_acc: 0.3103\n",
      "Epoch 4/100\n",
      "114/114 [==============================] - 0s 3ms/step - loss: 0.4010 - acc: 0.8333 - val_loss: 0.8884 - val_acc: 0.2759\n",
      "Epoch 5/100\n",
      "114/114 [==============================] - 0s 3ms/step - loss: 0.3331 - acc: 0.8772 - val_loss: 0.8519 - val_acc: 0.4138\n",
      "Epoch 6/100\n",
      "114/114 [==============================] - 0s 3ms/step - loss: 0.2963 - acc: 0.8947 - val_loss: 1.0697 - val_acc: 0.2414\n",
      "Epoch 00006: early stopping\n",
      "accuracy: 1.0\n",
      "lgbm_pre_res:  [[0.4207297 ]\n",
      " [0.41378006]\n",
      " [0.41335547]]\n",
      "Train on 114 samples, validate on 29 samples\n",
      "Epoch 1/100\n",
      "114/114 [==============================] - 2s 17ms/step - loss: 0.7053 - acc: 0.5526 - val_loss: 0.6616 - val_acc: 0.6897\n",
      "Epoch 2/100\n",
      "114/114 [==============================] - 0s 3ms/step - loss: 0.6783 - acc: 0.6754 - val_loss: 0.6502 - val_acc: 0.6897\n",
      "Epoch 3/100\n",
      "114/114 [==============================] - 0s 3ms/step - loss: 0.6449 - acc: 0.7105 - val_loss: 0.6288 - val_acc: 0.6897\n",
      "Epoch 4/100\n",
      "114/114 [==============================] - 0s 3ms/step - loss: 0.5691 - acc: 0.7281 - val_loss: 0.6277 - val_acc: 0.6897\n",
      "Epoch 5/100\n",
      "114/114 [==============================] - 0s 3ms/step - loss: 0.4831 - acc: 0.7719 - val_loss: 0.6432 - val_acc: 0.6897\n",
      "Epoch 6/100\n",
      "114/114 [==============================] - 0s 3ms/step - loss: 0.4376 - acc: 0.7982 - val_loss: 0.7057 - val_acc: 0.4828\n",
      "Epoch 7/100\n",
      "114/114 [==============================] - 0s 3ms/step - loss: 0.3921 - acc: 0.7895 - val_loss: 0.7642 - val_acc: 0.3793\n",
      "Epoch 8/100\n",
      "114/114 [==============================] - 0s 3ms/step - loss: 0.3508 - acc: 0.8246 - val_loss: 0.9116 - val_acc: 0.3793\n",
      "Epoch 9/100\n",
      "114/114 [==============================] - 0s 3ms/step - loss: 0.3108 - acc: 0.8333 - val_loss: 1.0428 - val_acc: 0.3448\n",
      "Epoch 00009: early stopping\n",
      "accuracy: 1.0\n",
      "embedded_pre_res:  [[0.2421752 ]\n",
      " [0.23053323]\n",
      " [0.22467212]]\n",
      "predict result: [[0.6629049]\n",
      " [0.6443133]\n",
      " [0.6380276]]\n",
      "predict month: 2018-07-28\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.\n",
      "[Parallel(n_jobs=1)]: Done  10 out of  10 | elapsed:    0.0s finished\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "self.embedded_columns: Index(['retail_sin', 'invest_yoy', 'primary_yoy', 'centre_project_yoy',\n",
      "       'lagging_idx', 'total_interest_ratio_acc_diff', 'id',\n",
      "       'finished_product_ratio_acc', 'main_business_tax_ratio_acc',\n",
      "       'financial_expense_ratio_acc', 'enterprise_total_loss_ratio_acc',\n",
      "       'vat_ratio_acc'],\n",
      "      dtype='object')\n",
      "lgbm_res.columns: Index(['retail_sin', 'retail_sin_yoy', 'invest', 'invest_yoy', 'primary_yoy',\n",
      "       'centre_project_yoy', 'num_acc_yoy', 'early_warning_idx', 'lagging_idx',\n",
      "       'pmi', 'growth_yoy', 'growth_acc_diff', 'enterprise_value_acc_diff',\n",
      "       'loss_enterprise_ratio_acc_diff', 'total_interest_ratio_acc_diff', 'id',\n",
      "       'enterprise_value_acc', 'loss_enterprise_value_acc',\n",
      "       'loss_enterprise_ratio_acc', 'current_asset_ratio_acc',\n",
      "       'finished_product_ratio_acc', 'main_business_tax_value_acc',\n",
      "       'main_business_tax_ratio_acc', 'financial_expense_ratio_acc',\n",
      "       'total_interest_ratio_acc', 'enterprise_total_loss_ratio_acc',\n",
      "       'vat_ratio_acc'],\n",
      "      dtype='object')\n",
      "Train on 115 samples, validate on 29 samples\n",
      "Epoch 1/100\n",
      "115/115 [==============================] - 2s 18ms/step - loss: 0.7547 - acc: 0.5652 - val_loss: 0.6691 - val_acc: 0.6897\n",
      "Epoch 2/100\n",
      "115/115 [==============================] - 0s 3ms/step - loss: 0.6695 - acc: 0.6957 - val_loss: 0.6576 - val_acc: 0.8621\n",
      "Epoch 3/100\n",
      "115/115 [==============================] - 0s 3ms/step - loss: 0.6045 - acc: 0.6783 - val_loss: 0.5854 - val_acc: 0.7241\n",
      "Epoch 4/100\n",
      "115/115 [==============================] - 0s 3ms/step - loss: 0.4390 - acc: 0.8609 - val_loss: 0.5557 - val_acc: 0.7241\n",
      "Epoch 5/100\n",
      "115/115 [==============================] - 0s 4ms/step - loss: 0.3552 - acc: 0.8696 - val_loss: 0.5684 - val_acc: 0.6552\n",
      "Epoch 6/100\n",
      "115/115 [==============================] - 0s 3ms/step - loss: 0.3184 - acc: 0.8522 - val_loss: 0.6704 - val_acc: 0.5862\n",
      "Epoch 7/100\n",
      "115/115 [==============================] - 0s 3ms/step - loss: 0.2907 - acc: 0.8870 - val_loss: 0.6658 - val_acc: 0.6207\n",
      "Epoch 8/100\n",
      "115/115 [==============================] - 0s 3ms/step - loss: 0.2584 - acc: 0.8783 - val_loss: 0.7468 - val_acc: 0.4483\n",
      "Epoch 9/100\n",
      "115/115 [==============================] - 0s 3ms/step - loss: 0.2186 - acc: 0.9130 - val_loss: 0.6423 - val_acc: 0.6207\n",
      "Epoch 00009: early stopping\n",
      "accuracy: 1.0\n",
      "lgbm_pre_res:  [[0.07120565]\n",
      " [0.06914113]\n",
      " [0.05458948]]\n",
      "Train on 115 samples, validate on 29 samples\n",
      "Epoch 1/100\n",
      "115/115 [==============================] - 3s 27ms/step - loss: 0.7166 - acc: 0.5391 - val_loss: 0.6704 - val_acc: 0.6897\n",
      "Epoch 2/100\n",
      "115/115 [==============================] - 0s 4ms/step - loss: 0.6594 - acc: 0.6261 - val_loss: 0.6640 - val_acc: 0.7241\n",
      "Epoch 3/100\n",
      "115/115 [==============================] - 0s 4ms/step - loss: 0.5919 - acc: 0.6870 - val_loss: 0.6671 - val_acc: 0.7241\n",
      "Epoch 4/100\n",
      "115/115 [==============================] - 0s 4ms/step - loss: 0.4987 - acc: 0.7478 - val_loss: 0.6670 - val_acc: 0.5862\n",
      "Epoch 5/100\n",
      "115/115 [==============================] - 0s 4ms/step - loss: 0.4174 - acc: 0.8087 - val_loss: 0.7083 - val_acc: 0.4828\n",
      "Epoch 6/100\n",
      "115/115 [==============================] - 0s 4ms/step - loss: 0.3557 - acc: 0.8696 - val_loss: 0.7684 - val_acc: 0.5862\n",
      "Epoch 7/100\n",
      "115/115 [==============================] - 0s 4ms/step - loss: 0.3012 - acc: 0.8783 - val_loss: 0.8887 - val_acc: 0.5862\n",
      "Epoch 00007: early stopping\n",
      "accuracy: 1.0\n",
      "embedded_pre_res:  [[0.21765725]\n",
      " [0.21877399]\n",
      " [0.22608766]]\n",
      "predict result: [[0.28886288]\n",
      " [0.2879151 ]\n",
      " [0.28067714]]\n",
      "predict month: 2018-08-28\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[Parallel(n_jobs=1)]: Using backend SequentialBackend with 1 concurrent workers.\n",
      "[Parallel(n_jobs=1)]: Done  10 out of  10 | elapsed:    0.0s finished\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "self.embedded_columns: Index(['retail_sin_yoy', 'invest_yoy', 'centre_project_yoy', 'num_acc_yoy',\n",
      "       'early_warning_idx', 'lagging_idx', 'growth_acc_diff',\n",
      "       'total_interest_ratio_acc_diff', 'id', 'finished_product_ratio_acc',\n",
      "       'vat_ratio_acc'],\n",
      "      dtype='object')\n",
      "lgbm_res.columns: Index(['retail_sin', 'retail_sin_yoy', 'invest', 'invest_yoy', 'primary_yoy',\n",
      "       'centre_project_yoy', 'num_acc_yoy', 'early_warning_idx', 'lagging_idx',\n",
      "       'pmi', 'growth_yoy', 'growth_acc_diff', 'enterprise_value_acc_diff',\n",
      "       'loss_enterprise_ratio_acc_diff', 'total_interest_ratio_acc_diff', 'id',\n",
      "       'enterprise_value_acc', 'loss_enterprise_value_acc',\n",
      "       'loss_enterprise_ratio_acc', 'current_asset_ratio_acc',\n",
      "       'finished_product_ratio_acc', 'main_business_tax_value_acc',\n",
      "       'main_business_tax_ratio_acc', 'financial_expense_ratio_acc',\n",
      "       'total_interest_ratio_acc', 'enterprise_total_loss_ratio_acc',\n",
      "       'vat_ratio_acc'],\n",
      "      dtype='object')\n",
      "Train on 116 samples, validate on 29 samples\n",
      "Epoch 1/100\n",
      "116/116 [==============================] - 3s 23ms/step - loss: 0.7456 - acc: 0.5517 - val_loss: 0.6598 - val_acc: 0.6552\n",
      "Epoch 2/100\n",
      "116/116 [==============================] - 0s 3ms/step - loss: 0.6692 - acc: 0.6034 - val_loss: 0.6641 - val_acc: 0.6552\n",
      "Epoch 3/100\n",
      "104/116 [=========================>....] - ETA: 0s - loss: 0.5797 - acc: 0.7019"
     ]
    }
   ],
   "source": [
    "pre_res_l = get_pre_signal(ml_test,sd_test,ed_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[-1, -1, -1],\n",
       " [-1, -1, -1],\n",
       " [-1, -1, -1],\n",
       " [-1, -1, -1],\n",
       " [-1, -1, -1],\n",
       " [-1, -1, -1],\n",
       " [-1, -1, -1],\n",
       " [-1, -1, -1],\n",
       " [1, 1, 1],\n",
       " [1, 1, -1],\n",
       " [1, 1, 1],\n",
       " [1, 1, 1],\n",
       " [-1, -1, -1],\n",
       " [-1, -1, -1],\n",
       " [1, 0, -1],\n",
       " [1, 1, 1],\n",
       " [1, 1, 1],\n",
       " [1, 1, 1],\n",
       " [1, 1, 1]]"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "[res_output(i) for i in pre_res_l]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_buy_sell_signal(pre_res,seq_len = 3):\n",
    "    '''\n",
    "    由于预测的是未来n个月（n=3）的的情况，预测有重合部分，将重合部分取平均，基于均值做买卖决策，提高精度\n",
    "    '''\n",
    "    length = len(pre_res)\n",
    "    l = []\n",
    "    for i in range(length):\n",
    "        if seq_len == 3:\n",
    "            if i == 0:\n",
    "                l.append(pre_res[0][0])\n",
    "            elif i == 1:\n",
    "                s = (pre_res[0][1]+pre_res[1][0])/2\n",
    "                l.append(s)\n",
    "            elif i == length-1:\n",
    "                l.append((pre_res[i][0]+pre_res[i-1][1]+pre_res[i-2][2])/3)\n",
    "                l.append((pre_res[i][1]+pre_res[i-1][2])/2)\n",
    "                l.append(pre_res[i][2])\n",
    "            else:\n",
    "                t = (pre_res[i][0]+pre_res[i-1][1]+pre_res[i-2][2])/3\n",
    "                l.append(t)\n",
    "        elif seq_len == 2:\n",
    "            if i == 0:\n",
    "                l.append(pre_res[0][0])\n",
    "            elif i == 1:\n",
    "                s = (pre_res[0][1]+pre_res[1][0])/2\n",
    "                l.append(s)\n",
    "            elif i == length-1:\n",
    "                l.append((pre_res[i][0]+pre_res[i-1][1])/2)\n",
    "                l.append(pre_res[i][1])\n",
    "            else:\n",
    "                t = (pre_res[i][0]+pre_res[i-1][1])/2\n",
    "                l.append(t)\n",
    "    return l\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "bs_signal = get_buy_sell_signal([res_output(i) for i in pre_res_l], seq_len = 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[-1,\n",
       " -1.0,\n",
       " -1.0,\n",
       " -1.0,\n",
       " -1.0,\n",
       " -1.0,\n",
       " -1.0,\n",
       " -1.0,\n",
       " -0.3333333333333333,\n",
       " 0.3333333333333333,\n",
       " 1.0,\n",
       " 0.3333333333333333,\n",
       " 0.3333333333333333,\n",
       " -0.3333333333333333,\n",
       " -0.3333333333333333,\n",
       " 0.0,\n",
       " 0.3333333333333333,\n",
       " 1.0,\n",
       " 1.0,\n",
       " 1.0,\n",
       " 1]"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bs_signal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_buy_month_list(signal,test_start_date,test_end_date):\n",
    "    test_month = get_month_list(test_start_date,test_end_date)\n",
    "    length = len(signal)\n",
    "    dic = {}\n",
    "    for i in range(next_n,length+1):\n",
    "        l = []\n",
    "        for j in range(next_n):\n",
    "            l.append(signal[i-(next_n-j)])\n",
    "        dic[test_month[i-next_n]] = l\n",
    "    return dic\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "dic = get_buy_month_list(bs_signal,test_start_date,test_end_date)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'2018-06': [-1, -1.0, -1.0],\n",
       " '2018-07': [-1.0, -1.0, -1.0],\n",
       " '2018-08': [-1.0, -1.0, -1.0],\n",
       " '2018-09': [-1.0, -1.0, -1.0],\n",
       " '2018-10': [-1.0, -1.0, -1.0],\n",
       " '2018-11': [-1.0, -1.0, -1.0],\n",
       " '2018-12': [-1.0, -1.0, -0.3333333333333333],\n",
       " '2019-01': [-1.0, -0.3333333333333333, 0.3333333333333333],\n",
       " '2019-02': [-0.3333333333333333, 0.3333333333333333, 1.0],\n",
       " '2019-03': [0.3333333333333333, 1.0, 0.3333333333333333],\n",
       " '2019-04': [1.0, 0.3333333333333333, 0.3333333333333333],\n",
       " '2019-05': [0.3333333333333333, 0.3333333333333333, -0.3333333333333333],\n",
       " '2019-06': [0.3333333333333333, -0.3333333333333333, -0.3333333333333333],\n",
       " '2019-07': [-0.3333333333333333, -0.3333333333333333, 0.0],\n",
       " '2019-08': [-0.3333333333333333, 0.0, 0.3333333333333333],\n",
       " '2019-09': [0.0, 0.3333333333333333, 1.0],\n",
       " '2019-10': [0.3333333333333333, 1.0, 1.0],\n",
       " '2019-11': [1.0, 1.0, 1.0],\n",
       " '2019-12': [1.0, 1.0, 1]}"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dic"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_month_buy_signal(dic,test_start_date,test_end_date,seq_len = 3):\n",
    "    '''\n",
    "    获取每月买卖信号，卖出信号为[0,0,0]、[1,0,0]、[1,1,0],001、010、011、101、111为买入信号，信号分析没有考虑做空\n",
    "    input:\n",
    "    dic: dic,key为月份，value为对应的信号\n",
    "    ''' \n",
    "    test_month = get_month_list(test_start_date,test_end_date)\n",
    "    dic_month_signal = OrderedDict()\n",
    "    for m in test_month:\n",
    "        l = dic[m]\n",
    "        if seq_len ==3:\n",
    "            if (l[0]<0.5) & (l[1]<0.5) & (l[2]<0.5):\n",
    "                dic_month_signal[m] = 0\n",
    "            elif (l[0]>0.5) & (l[1]<0.5) & (l[2]<0.5):\n",
    "                dic_month_signal[m] = 0\n",
    "            elif (l[0]>0.5) & (l[1]>0.5) & (l[2]<0.5):\n",
    "                dic_month_signal[m] = 0\n",
    "            else:\n",
    "                dic_month_signal[m] = 1\n",
    "        elif seq_len ==2:\n",
    "            if (l[1]<0.5):\n",
    "                dic_month_signal[m] = 0\n",
    "            else:\n",
    "                dic_month_signal[m] = 1\n",
    "    v = list(dic_month_signal.values())\n",
    "    df = pd.DataFrame(v,index=dic_month_signal.keys(),columns=['signal'])\n",
    "    return df\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "month_signal = get_month_buy_signal(dic,test_start_date,test_end_date,seq_len = 3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>signal</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2018-06</th>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2018-07</th>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2018-08</th>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2018-09</th>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2018-10</th>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2018-11</th>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2018-12</th>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-01</th>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-02</th>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-03</th>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-04</th>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-05</th>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-06</th>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-07</th>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-08</th>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-09</th>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-10</th>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-11</th>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-12</th>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         signal\n",
       "2018-06       0\n",
       "2018-07       0\n",
       "2018-08       0\n",
       "2018-09       0\n",
       "2018-10       0\n",
       "2018-11       0\n",
       "2018-12       0\n",
       "2019-01       0\n",
       "2019-02       1\n",
       "2019-03       1\n",
       "2019-04       0\n",
       "2019-05       0\n",
       "2019-06       0\n",
       "2019-07       0\n",
       "2019-08       0\n",
       "2019-09       1\n",
       "2019-10       1\n",
       "2019-11       1\n",
       "2019-12       1"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "month_signal"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_month_profit(stocks,start_date,end_date):\n",
    "    '''\n",
    "    获取月收益率数据，数据为本月相对于上月的增长率，计算时用每月最后MONTH_MEAN_DAY_NUM天的均值\n",
    "    input:\n",
    "    data:dataframe,index为股票代码，values为因子值\n",
    "    start_date:str, 初始日期\n",
    "    end_date:str,终止日期\n",
    "    output:\n",
    "    month_profit_df: Dataframe,columns为每月第一天的收盘价\n",
    "    \n",
    "    '''\n",
    "    start_year = int(start_date[:4])\n",
    "    end_year = int(end_date[:4])\n",
    "    start_month = int(start_date[5:7])\n",
    "    end_month = int(end_date[5:7])\n",
    "    len_month = (end_year - start_year)*12 + (end_month - start_month) + 2\n",
    "    price_list = []\n",
    "    month = start_month-1\n",
    "    year = start_year\n",
    "    for i in range(len_month):\n",
    "        year = year + (month + 1) // 13\n",
    "        month = month % 12 + 1\n",
    "        date_s = str(year)+'-'+str(month)+'-'+'01'\n",
    "        date_e = str(year)+'-'+str(month)+'-'+'20'\n",
    "        price_close = price.loc[date_s:date_e]['close'][0:1]\n",
    "        #print(price_close)\n",
    "        #price = get_price(stocks,fields=['close'],count=1,end_date=date)['close']\n",
    "        price_list.append(price_close)\n",
    "    month_profit = pd.concat(price_list,axis=0)\n",
    "    v = list(month_profit.values)\n",
    "    month_profit_df = pd.DataFrame(v,index=month_profit.index,columns=['profit'])\n",
    "    return month_profit_df\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "month_profit = get_month_profit(select_index,test_start_date,test_end_date)\n",
    "month_profit_pct = month_profit.pct_change(1,axis=0).dropna(how='all')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_strategy_profit(month_signal,month_profit_pct):\n",
    "    length_signal = len(month_signal)\n",
    "    length_pct = len(month_profit_pct)\n",
    "    if length_signal != length_pct:\n",
    "        print('input references must have same length')\n",
    "    month_profit_pct_shift = month_profit_pct['profit'].shift(-1)\n",
    "    month_signal['profit'] = month_profit_pct_shift.values\n",
    "\n",
    "    month_signal = month_signal.dropna()\n",
    "    month_signal['profit'][month_signal['signal']==0] = 0\n",
    "    month_signal['selct_profit'] = month_signal['profit']\n",
    "    month_signal['cumprod_profit'] = (month_signal['selct_profit']+1).cumprod()\n",
    "    month_signal['cumsum_profit'] = month_signal['selct_profit'].cumsum()\n",
    "    return month_signal\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "strategy_profit = get_strategy_profit(month_signal,month_profit_pct)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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Xjf7DMSqal4TK84Ljm3P7dNA6AiPNwJn5c0BnK0d5o/keF33bQAu93Sc3hgvzl5OB1zHbwAmj+BYf4Xz80E6zmlVI+W5fRZnb8lm1/FfcG13e84RGut1ru8bgULg7YH6/fX0l3EFICIiIiIiIiIicgr1OBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbeUOBIREREREREREbf8hnoAXYmJibGTJk0a6mGIiIiIiIiIiIwYu3btKrHWxvZkX69OHE2aNImdO3cO9TBEREREREREREYMY0xOT/fVVDUREREREREREXFLiSMREREREREREXFLiSMREREREREREXFLiSMREREREREREXFLiSMREREREREREXFLiSMREREREREREXFLiSMREREREREREXFLiSMREREREREREXFLiSMRERER6ZN3Dxfy/VcPDPUwREREZAApcSQiIiIiffKvnXk8vTWX3NK6oR6KiIiIDBAljkRERESkTw6fqAJgw5GiIR6JiIiIDBQljkRERESk1yrrm8kvrwdgQ3rxEI9GREREBooSRyIiIiLSa6muaqPJMSF8dLSEhubWIR6RiIiIDAQljkRERESk1w4fdyaO7rpgCg3NDrYdKxviEYmIiMhAUOJIREREZBRzOGyP9mtpdXC0uIYN6UU0NLdy+EQVMaGBXD1/PIF+Pryfpj5HIiIiI5HfUA9ARERERIbGg2vTeHl3Ppu+exH+vl1fT7zl0W3tVUW3r0zm8PEqZo8PJ8jfl5VTovngiPociYiIjESqOBIREREZhZ74KJs/bzhKYVUjRdWN3e5/+EQVF82M47qFE3hqaw5HCquZPS4cgAumx3KspJbsktqBHraIiIgMMiWOREREREaZPbnl/Ojfh5gQMQaAwqqGLvdvanFQ3dDC/MQI7r9qDhHBAbQ4LLPHuxJHM+IA2JCu6WoiIiIjjRJHIiIiIqPMQ+9lEBEcwEM3LQCgsLLrxFF5XRMAUaEBjA325/ufnIW/r2FhUgQAk2JCSIkJ4f10TVcTEREZadTjSERERGSEeX3fcVodDiZGhZAcHUx0SADGGAB255bz4ZFi7r1iJpNjQ4DuK45Ka5yJo5iQAACuX5TIFXPHMSbAt32fC2bE8s9tudQ3tZ6yXURERIY3JY5ERERERpDsklq+/uyeU7aFBPgyMTqE5KhgsktriQoJ4LYVyYzx98Xf11DYTY+jslpXxZErcQSckRy6YEYc/9iczdasUi6cGeehaERERGSoKXEkIiIiMoLszCkH4NHPLMEYyCmtI7esjpzSWo4UVXO8op77rphFSKDzbWBcWFC3U9VKa52JpejQgE73WZ4SRZC/DxvSi5Q4EhERGUGUOBIREREZQXbllBMW5MdFM+Pw8THd7h8XHkhhddeJo48rjgI73SfI35ezp8Twfnox91vbPjVOREREhjc1xxYREREZQXbnlLNoYmSPkkYACeFBFFZ1PVWttKYJHwMRY/y73O/CGbHkltVxrKS2x+MVEREZaJszS9iXVzHUwxi2lDgSERERGSEq65s5UlTN4uTIHh8TH96TqWpNRAYHdJuMumCGc4qaVlcTERFv8p0X9/PpR7awMUN/n/pCiSMRERGREWJvXgXW0qvEUVx4INWNLdQ2tnS6T1ltY5f9jdokRQUzJTaEDelF7duqG5qprGvu8XhEREQ8qbqhmYKKelodli88sZN/7czDWjvUwxpWlDgSERERGSF2ZZfhY2B+UkSPj0kIDwKgqIuV1cpqm05ZUa0rF86IY1tWGbWNLVTUNXH1w5v5yj9393g8IiIinpRZVAPAz64/i/mJY/nvF/dz89+2UlrT9TTtjnbllHGwoHKghuj1lDgSERERGSF25ZYza1w4oYE9X/8k3pU4OtnFdLXS2iaiu2iM3dFlcxNoanVw62PbuOvpXRwrqVXPIxERGTIZhc7E0fKUKJ6/cyU/v/4s9uRW8LnHd1DTRbVtm4bmVm59dDtX/mETN/7lI3bllA30kL2OEkciIiIiI4C1lgP5lcxL7Hm1EXycOCrqYmW13lQcLZ0UxR9uXkhmYQ1bs8qYGhdKUXUDDoemBYiIyOA7UlhNoJ8PiZHB+PgYbl42kT/dsohDx6u4++ld3U5b25NbQX1zK59alMjJqgZaHYM0cC/S48SRMcbXGLPHGPOG6/sUY8w2Y0yGMeZ5Y0yAa3ug6/tM1/2TOjzGfa7t6caYyzwdjIiIiMhodaKygaqGFmaPC+vVcfHhzkqiwir3iaOWVgcVdc09ThwBXDV/PP+55zz+/tkl3Lp8Is2tlvK6pl6NS0RExBOOFNUwNS4U3w4LPKyeFc8Pr5rNxowS3jpwssvjtxwtwcfAD6+ezYZvX8jSST3vIzhS9Kbi6BtAaofvHwQestZOA8qBL7i2fwEot9ZOBR5y7YcxZjawBpgDXA78yRjj27/hi4iIiAhA2skqAGaOC+/VcaGBfgQH+HKy0n2vh3JXY+ueNMfuKDEymItmxpMw1lnRVFjV814SIiIinpJRWM30+DMvqtyyPJkZ8WH88u00mlo6LyP66Ggp8xIjCA/yx9fHYEzXK4yORD1KHBljEoFPAo+6vjfARcCLrl2eAK513b7G9T2u+1e79r8GeM5a22itPQZkAss8EYSIiIjIaJd2shrA7ZvjrhhjSAgPorCTqWpltc5Kod5UHHUUF96WOOp8KpyIiPReXVML1/5xM+8dLhzqoXitqoZmTlQ2MC0+9Iz7fH0M914xk5zSOp7dnuv2+NrGFvbmVXD2lOiBHqpX62nF0e+A7wBtabhooMJa29ZJKh+Y4Lo9AcgDcN1f6dq/fbubY9oZY+40xuw0xuwsLi7uRSgiIiIio1faiWomRIxh7Bj/Xh8bFx5I6okqGppbz7ivtNZZKdTT5tini1fiSERkQLx96CR78yr46VuptIzGxjs90NYYe3qc+4sqF8yIZcXkKH6/LoPqhuYz7t+eXUaLw3L2lJgBHae36zZxZIy5Eiiy1u7quNnNrrab+7o65uMN1v7VWrvEWrskNja2u+GJiIiICM6pajMTeldt1ObWFckcK6nl84/voK7p1BVm2iqOejtVrU1cmDPhdFKJIxERj3p5dwGBfj4cK6nllT0FPLklm/te3q/FCDrIKOy6GtcYw31XzKK0tom/fZjVvv21vQXMu/9t7nvpAAG+PixOHn19jTrqScXROcDVxphs4DmcU9R+B0QYY9rWek0Ejrtu5wNJAK77xwJlHbe7OUZERERE+qixpZWjxbXM7GVj7DZXzhvPb26cz9asUlb/5gP+sfkY9U3O6qP+TlXz9/UhJjRAPY5ERDzoRGU9mzJL+NKqycwZH87/vHKQ/33tEM9uz+PdVE1dA6isa+b1fccZ4+9LYuSYTvebnxTBlfPG8beNxyhyXeR4aksOgf6+xIUH8umliYwJGN3tmbtNHFlr77PWJlprJ+Fsbr3eWnsL8D5wg2u324HXXLdfd32P6/711rm+3evAGteqaynANGC7xyIRERERGaUyi2podVhmJvSuMXZH1y9K5Jk7VpAUFcyP/n2Ycx9czx/fzyS7pA5jIDK4b4kjcE5XK1LFkYiIx7y65zjWOl+7v3v5THx9DN+5fAbJ0cE8vD6z2yXmR7otR0u54v8+ZPuxMu69YiY+Pl03tP7vy2bQ4nDw0HsZ5JXVsTOnnM+ePYnXv3ouD1x71iCN2nv5db9Lp74LPGeMeQDYAzzm2v4Y8JQxJhNnpdEaAGvtIWPMC8BhoAX4irX2zIn0IiIiItIjza0O9uVVtDfG7utUtTYrp0SzcspKdmSX8fD6TH71djoAkcH+pyxj3Fvx4UGaqiYyArT10fHz7c3i3OJpR4tr+PvmYyxOjmRSTAiTYkI49KPL8PExRAUHcO/LB/gwo4Tzp4++1i9NLQ5+8246f/0wi0nRIbx099nMT4ro9rjk6BBuWZ7MU1tz2ldYu3r++IEe7rDRq8SRtXYDsMF1Ows3q6JZaxuAGzs5/qfAT3s7SBERERE50/M78vj+qwcBCPD1ISUmxCOPu3RSFE98fhkH8iv5ywdH+9zfqE18eCD78ys9MjYRGRqZRTV87vHtTIoO4YnPLWuv4PjXzjx+/U46V84bz83LJjI17szVq8RzDh2v5DOPbccYeODaue3b256P6xcl8n/rMvjLhqOjLnGUWVTDPc/v4WBBFTcvS+IHV84mOKDnKY+vXTSVF3fl89LufBYnR5IUFTyAox1e+lNxJCIiIiJDaEN6MQnhQXzirHHEhQd6vArgrMSx/PGWRf1+nPjwIEprG2ludeCvSgWRYWdXTjlfeGIHjc0O8srqeWZbDretnATA24cKqapv4ckt2Ty26RjLU6L4r+UTuXxuAoF+o7svjKftyinns//YTmigH0/fsZwpsWcm6QL8fLh1RTK/ejud7JJaJnnogsJwcOeTOymva+KR2xZz2ZyEXh8fHRrIXedP5tfvHOGaBao26kh/uUVERESGoZZWB1uzSrlwZhz/e9Vs7jp/ylAPqVPx4UFYC8XVapAtMty8e7iQWx7dSsQYf9becx7nTYvh5/9JI6+sDmste/MquGJuAh/du5rvXD6D45X1fOO5vaz8+Xp+9lYqOaW1Qx3CiLApo4TbHttGdEgA/7prpdukUZtPLUrEx8ALO/MGcYRDq7GllaySWm4/e1KfkkZt7jhvMvdfNZsbFyd1v/MoosSRiIiIyDC0L7+CmsYWzpsWM9RD6VZ8eCAAhepzJDKsPLs9ly89tZMZ8WG8ePfZJEeH8ItPzaOl1fL4R9kUVNRTUtPIgokRxIYF8uULpvLBty/kyc8vY9mkKB7bdIyrH95MbWPLUIfSLwUV9TS2DF173ncOneTzj+9gYlQwL9y1ksTIrqdQJYwN4sIZcfxrV357X6qRrrDSeWFifETnq6f1RJC/L589J2XUr6J2OiWORERERIahjRklGAMrJ0cP9VC6FR8eBChxJDKc/N97Gdz38gFWTY/ln19cQUyoMwE8IWIM50yN5p3DJ9mbVwHAgg7Nh318DKumx/KX2xbz0E0LqKxv5ljJ8K06Olpcw0W/3sC3nt83JOcvrm7ky8/sZtb4cJ67cwVxYUE9Ou6mpUkUVzfyfnrxAI/QOxRU1AOQ2M/EkbinxJGIiIjIMLQpo4SzJowlMqR/jasHw8eJI01VExkO9uSW89B7R7h+0QT+9pklhASe2hr30jkJ5JXV8/yOPAL8fJiZEO72cabEOvvr5JbVDfiYB0Krw/KdF/fT2OLgzQMn2hNlg+lIYTUtDst3L59BRHDPX+8vnBlHbFggz+/o33S1HdllzPrBWvK8/Dk87koc9bfiSNxT4khERERkmKluaGZPXgXnTvX+aWoAUcEB+PsajlfWD/VQZABYaymqbqCheeim8ohnPbc9j+AAX358zVy3De1Xz4rDGGfl49zx4QT4uf9YmRztTBzllHp30qEzT27JZldOOT+5Zg7RIQE8+J80rLWDOoZsV4+otv/LnvL39eFTixJ5P72oX9We61KLqG9uZVNmSZ8fYzC0JY4SxvasIkt6R4kjERERkWFmW1YZrQ7LucOgvxE4p66kxIRwtGj4TlcR917bW8C8+99h2U/X8bVn9wz1cMQDahpb+Pf+41w5bxyhge4X4Y4LC2Kha3ragqTITh8rNNCP6JAAcsvO/N1va/bsrU3zc0pr+eXadC6cEcutK5L56kVT2ZJVynupRYM6jtzSOgL8fBgX3vuEyE1Lk2h1WF7cld/n8+/MLnP9W97nxxgMBRX1xIQGEuSv3kQDQYkjERERkWFmU2YJQf4+LE7u/AObt5keH8aRwuqhHoZ42Eu7CwgN8mPZpCi2ZZXicAxuNYZ43hv7jlPX1MpNSyd2ud+lrpWrFk6M6HK/idHBZ1QcHSup5e5ndrExo4Sf/ye1fwMeAA6H5d6XDuDnY/jZ9WdhjOGW5cnMTAjjf145QGVds8fP2dTivol1dmktSZFj8PExvX7MlJgQlqdE8cLOvD79bjY0t7I/vxKAnTllvT5+MBVU1DMhQtVGA0WJIxEREZFhZmNGMctSogn0Gz5XVmfEh5FbVjfsV1eSjzW3OtiVXcbFs+L51OIJVDW0tE+rkeHrhZ15TIsLZVE3CaEbFidy05Ikzp8R2+V+yVGnJo7qmlq488md+PkYblycyMu7C9iWVeqRsXvKszty2ZJVyvc+OYtxY509cwL8fPj1jfMprW3i7md2cccTO/jZW55Jer2+7zjzfvQ27x0uPOO+nNI6JvVymlpHa5YlkVNax7ZjvU/8HCyopKnVwZLkSHJK67y2OgycU9UmRKq/0UBR4khERERkGDlRWc/R4lrOGyb9jdpMTwgDIKOoZohHIp5ysKCS2qZWlk+OYl6iM8nQVp0gw1N1QzN78yq44qxxGNN1hUtMaCAP3jCP8CD/LvebGB3Cicr69oqah949QkZRDX+4eRE/vmYuEyLG8IPXDtLsJcvGF1TU8/O30jhnajRrliadct/cCWP52kVT+ehoKRszSnh6a06/q+w+OFLMt57fS0OzgwfePHxK5ZG1ltyyOiZGB/f58a+YO46wID+e35Hb62N35jinp911/hQAdnlp1ZG1luMVDYwfq8TRQFHiSERERGQY2ZThbFA6XPobtZnpShwdOel+ulqrw/L8jtwBmQIiA6OtgmF5SjTT4kIJ8vdhX/7grzolnrMntwKHhaWTPDcNNjkqGIeF/PI6DhZU8timY9y8LIlzp8UwJsCXH141myOFNTy+Odtj5+wray3fe/kADmv5xfXz3CbPvrF6Gtv/ZzU/vGoOdU2t/Wr6vye3nLue2sW0+DD+cPNCskvreHprTvv9xTWN1DW19qviKMjfl2sXTOCtgyd7/fq6M7uMyTEhrJoeS6CfDzu8tM9RRV0z9c2tWlFtAClxJCIiIjKMbMosISY0oD0RM1wkRQYT5O9DWieJo0c+PMp3XzrAs324Ki5DY2tWKVNiQ4gNC8TP14ezJoxl3xAsVy6eszOnHB8DCyd6MHHkqpbJKa3je68cIDo0kHuvmNV+/yWz41k9M47fvXeEk5V9X/3LE7ZmlfHBkWL++7IZJEW5r/IxxhAXFsS0+FCg71WUmUXVfO7xHcSFB/LE55dy5bxxnDctht+vz6C6wZngyXVN8etPxRE4m2Q3tTh4bV/BGfd1tkqcw2HZmVPOkkmRBPj5MD8xor0CydsUuFZUU+Jo4ChxJCIiIjJMOByWzZklnDM1pttpJN7Gx8d02iD7QH4lv33nCAA7+tCHQwZfS6uDndnlrJgc3b5tXmIEh45Xec2UI+m9ndllOIqvxAAAIABJREFUzBoX3ulqan3RlvT4++Zj7M+v5DuXzWDsmI+ntxljuP/qObQ4LD9583D79obmVo+Noac+OlqCj4EblyR1u+/UWGfi6GgfEkcFFfXc9th2/H19eOrzy4kLC8IYw3cum0lFXTNPb3Um0LNdiaP+VByBc4rdnPHh/PXDLL7z4j5+9XYamUU1/PaddGb+YG17JWtHD65No6KumfOnxwFw9tRo9udXkDlI041bWh28deAEGYXVbpNbtY0tvJ9exCt78skvdyaOJihxNGA894ogIiIiIgMq7WQ1JTVNnDvM+hu1mR4fxgdHitu/P15Rz3Pbc3lmWy4xoYEsSIpgi2tlrr6sICSD5/CJKmoaW1h+SuJoLI0tDo4UVjNn/NghHJ30RUurg715Fdy4ONGjjxsbGkhwgC8bM0pIjBzDtQsnnLFPUlQwX7lwKr999whrlhaTdqKaX7+TzmtfPYeZCeEeHU9Xth0rY+6EsT1KnEWGBBATGkBGYeeJlIbmVnyMIcDv43qNstomPvPYNmoaWnj+SytPqSY6K3Esq6bH8timLD53ziRyS2vxMZ5JiHzxvMl875UDfHCkmJKaJv74/lEA/HwML+7KO2X68+Obj/HIh1nctiKZT5zlXD3v1hXJPPJBFg+vz+B3axb2ezzdeWl3Pt996QDg7Ke1YnIUK6dEsyApglf3FPDElpz2flCzxjl/RtQce+AocSQiIiIyTGzOdF4VPm9a16sYeauZCWG8uCuf1/YW8O99x1mfVoQFLpgey7cvm0HqiWrWHjrJkaLqQf2wKL231bUK1oqUqPZt810NsvfmVTBn/Fiyimt453AhX1o1edhVyI1GqSeqqWtqZfGkqO537gVjDBOjgkk7Wc3dF0zB39f9pJc7V03m5d35fPP5vZTUNAHw1v4Tg/Za0NDcyt68Cm5fmdzjY6bGhZJR5H76bVOLg2se3syUuBD+dMvi9u2/X5dBblkdT39hObPHnxnbVy+cyqcf2cJz23PJLq1jfMSYUxJPfXXtwgntSbuTlQ28sf84MxPCeXVvAW8fOklTi4MAPx/WHjzJj944zCWz47n/6jntv7sxoYF8ZmUyf9uYxddWT2OKq+LKneySWuLDgxgT0PeVP/+5PY8psSHcuWoyW46WsiWrlDf2nwDAGLhu4QSuWziBJ7fk8O7hQoL8fYgM7rpRu/SdEkciIiIiw8TGzBKmxoWSMDZoqIfSJ9PjnX2ZvvHcXmJCA7n7gimsWTqxvZdIWKDzTf+OY2VKHHm5bVnOprlx4R//LCZHB5MUNYbX9hznluXJPPBmKuvTijh/emx7RYB4r52uFbM82Ri7zfT4MCrrm7mhi2qmIH9ffnTNXG7/+3aWJEfS4rC8m1rEty6d4fHxuLM3r4KmFgfLU6K739llalwor+09jrX2jOToo5uySC+sJrO4hpKaRmJCA2lpdfDG/uNcPCv+lGq9jpalRLEsJYqfvJlKkJ+PR/tNtUkYG8Qd500GoL65lRd35bM1q5SQQF++8dweFiRF8Ps1C/E9rfLzi6sm8+SWHB754Ci/vGG+28dOP1nNVX/YxHnTYnjss0v7NL7UE1Xsy6vgB1fO5qalE7lp6USstWSV1LI7p5x5iRHMcPX5m58UwdV/2ESQv68S1ANIiSMRERGRYaChuZXtx0pZs3TiUA+lz5alRPHF81JYODGSi2fFn3EVPSlqDAnhQWzPLue2lZOGZpDSrVaHZXt2GVfOG3fKdmMMnz07hZ+8cZiXduWzPq0IgHWphUocDQPbj5UxIWIM4wZgSfOfXDOXhpZWAv26rkA5f3osL961kpnjwnlmaw4//08aBRX1g9K7ZltWGcbA0pSeV1xNiwujuqGF4urGU5Ko+eV1/GFdJvMSx7I/v5J/7zvO585JYUtWKSU1TVw9f3yXj/unWxbxx/cz+ee2XOYlDuy0z/OmxRAc4MvfNx9jb14F4yPG8NjtS91WC8WEBnLx7Hg+PFLiNlnW3OrgWy/spcXhYF1aERszivtUIfvc9lwCfH24vsO0RmMMU2JDz6h0Cg/y58W7z6aucfB7Yo0mao4tIiIiMgzszimnodkxbPsbgbOi4H8+OZtPnDXO7dQLYwxLU6LYfqy005V+ZOilnqiiuqHllMbYbT69JJGwQD+++9J+Av18mBIbwnupRUMwSumNllYHmzJLBuz1ZWywP/HhPauUXDIpitBAPy6eHQ84E4+DYduxUmYlhJ/SuLs70+JOXVkts6iG+18/xOW/2wg4E0BzJ4Tz8m7namav7z1OaKAfF86M6/JxY0ID+eFVc9j3w0v51iXT+xJOjwX5+3L+9Fg2pBfj52N44nPLiAoJ6HT/JcmRnKxq4LibFfAeevcIh45X8bs1C5kYFcwDb6TS0stm+Y0trbyyp4DL5yYQ2cU4OooJDez3ynPSNSWORERERIaBTZkl+PkYVkzp+TSK4WjZpEgKqxrJK6sf6qFIJ9r6G7mb0hMW5M+aZUm0OCw3LknkmgUT2JdfQXF142APs0/Ka5uGeghDYm9eBdUNLZw/w3v6p02JDWVyTAjvHh74xFFjSyu7c8tZ1otqI4Cp8c7E0b925nHro9u4+Lcf8M9tuVw6O56X7j6bxMhgrl+YyIGCSl7enc/aQye5dE48Qf496/0T5O+LXyc9oTzp5mUTmeCqNOouAbM42Tl1bmf2qStgProxiz9tOMpNS5K4ev547rtiJumF1fxjc3avxrLlaClVDS1cu7DrqiwZXEociYiIiAwDaSermRYf5tFlsr1R2zSR7ad9KBHvse1YGcnRwZ322rrjvMlcPCuOu86fwsWz4rEW3k/z/qqjN/efYNED73KwoHKohzLoPjhSjK+P4Rwvq2hcPSuOrVmlVDc0D+h5th8ro6HZwarpvYs/NjSQsWP8eXXvcY4W1/Dfl83go/su4rc3LWhvfH31gvEE+vnwrRf2Ud3QwnVuVpUbaqumx7LpuxcyPymi231nJoQRHODLrpzy9m1PbcnmgTdT+cRZCfz0urkAXD43gYtnxfOrd9LJ7KSBuDvvHi4kOMCXs6d418/iaKfEkYiIiMgwUFnfTFTIyF8xZnpcGGPH+LPjmBJH3sjhsGw/VsaKLhoIx4cH8ejtS0mMDGbWuDDGjw3i3UGabtRXDc2t/Oyt1GGT5PK0D44UsyApolfTtAbDxbPiaW61bMwoGdDzvJ9WTICfDysn9y5ZYYzh/9Ys4JHbFrPxOxfylQunEhMaeMo+MaGBvP/tC3jp7rN55ctne+104542lvbz9WHhxAh2ZjsTRy/syOMHrx3i4llx/N+ahe0VUsYYfnb9XEICfPnWC/todXQ//djhsLyXWsiqabE9rsqSwTGyL1mJiIiIjBBV9c3EhXW+/PFI4eNjWJIcyQ5VHHmltJPVVNY3s3xyz6b0GGNYPSueF3fl09DcOuQfBl/enc9fP8wiLjyIKbEhTIkNZWpcKJsySiioqCci2J/NR0v42uppQzrOwVRa08iBgkq+efHA9tLpi8XJkUQE+/Pe4UI+cda47g/oow3pRaycHN2n5eMvmNF1vyKA8RFjGD8IDb4Hy+LkKB5en8HTW3P4wWsHWTU9lj/esgj/06bVxYUFce8VM/nuSwc4UFDJgm4qmg4er6SwqpFLXP2txHuo4khERERkADgclsc2HfNYb5eqhmbCg7yrGmCgLE2JIqukdtj0xRlN2vsbdbKUuDurZ8VR39zKlqOlAzWsbllr+cV/0vjWC/sAKKtt5LnteXz/1YOs+etWHn4/k0tnx3PDokR251RQ3zQ6VmiqrG/mwbVpWOtc0czb+Pn6cOGMON5PL6KhuZX7Xz/k8Z+j7JJaskpqudCL+jt5u8XJkTgsfP/VgyxPieKRWxd3umLexbOcSaBNGcWdPl5eWR0v7MjjyS05+PoYLuqmebgMPlUcDbHK+maq6ptJilIXeBERkaGSWVTN/a8f5o+3LPLYVI09eeX85I3DHD5exW8+Pb/fj1dV30L4mNHx1m3pJGc1y87sMq4YwCoD6b1tx0pJihrTq+XRV06JJiTAl/dSC7tdTWqgHCyo4i8fHOXTSxL56XVn4e/rg8NhOVHVwNGiGnLL6rhsTgIHCyp5dNMxduWUc+4075xS5Cn55XVc+8ePKK1t5PaVyZw1YWCXfe+ri2fF88qeAm57bBs7sst5bW8Ba+9Z1eNV2rrzfrpzamJPKofEaeHECIL8fZgzfiyP3b60y0qt6NBA5owP58OMEr560ZmVfK0Oy93P7OJgQRUAKydH93g1NRk8qjgaYj987SAX/WYDr+0tGOqhiIiIjFr/2pXPpswSPsr0XB+Ntqvir+zJ52hxTb8eq6nFQX1z66ipODprwliC/H3UIHsQORyWQ8cr+cfmY502sm3rb+RuNbWuBPr5ct60WNalFmFt931OBsK6tEKMgXuvmNU+ncbHxzAhYgyrpsdy64pkYsMCWZoShZ+PYfPRge2p4w0eXJtOTWMzr375HH50zVx8fHrW42awrZoeg7+vYUd2OdcuGE9Ds4P/98I+HD3omdOdjMJqntmWy+SYECbFhHhgtKNDeJA/737zfP75xeWE9GDBhnOnxbAnt5zaxpYz7vvnthwOFlTxwLVzeeaO5fxuzYKBGLL00+i4bOWlrLVsyizFWvjGc3s5WlTD11dPG5QlF0VERORjH6Q7S+h35pR7rMLlo6OlTIwKpqSmkV+tTeempUlkFtVwtLiGmNBAPjlvHLPGhffosdpWFAr3ssa1AyXAz4cFSRHqczTAjlfUsymjhI2upGmpayn6K+Ym8OdbF7fvV9fUQm1jK6W1jZTXNbOiF9PU2qyeFcfaQyc5dLyKuUNQ2bI+rYhFEyOJ6qaSITTQj/lJEXw0hNPqBsOe3HL+ve84X79oao9W0hpKYUH+XDlvPJX1zfz6xvksn5zPfS8f4NFNWdy5akqvH6+uqYUPjxSz9uBJ3th/gpBAP359Y/+rQkeb3syYWTUtlkc+yGLbsVIumumculbX1MLWrFJ+9XY6506N4ZblE3vcoFsGnxJHQyi7tI6Smkbuv2o2B49X8fv1mXyQUcJjty85oxu/iIiIDIyTlQ2knXRWWOz0UKKiobmVXTnl3LoimQA/H/684ShrD50EIDokgIr6Zh5+P5P/W7OAaxZ0vzRzZb0zceRtKx4NpGUp0Ty8PoPqhmbCRkml1WApq23iV2+n8dyOPKyF2LBAVk2P5dypMfzn4El25pRjrW3/EPfAm6m8vDufS2cnALA8pWeNsTu6aGYcxsB7qYWDnjgqrGpgf34l/33ZjB7tf87UGB5en0FFXRMRwSNvyoy1lgfeTCU2LJAvnd/7xMtQeOimj6tQ1ixN4oP0Yn71djpnT4np0c9TRV0T61KLePvQST7MKKah2UFEsD9rliVxz8XT9dlrgC1OjiTQz4eXdhWQeqKajRnF7Mopp7nVMnaMP/dfPUdJIy+nxNEQ2n7MeSXj3GmxfPacFM6fHsvXnt3Dv3bmc/cF7l/EG1taeWZrLresmNhpAzIRERHpuQ+POKuNVs+M44MjxdQ3tfZpZZ2O9uRW0NjiYOXkaM6ZGsPMhDAmRIxhalwoEcEBlNQ0csOfP+LFXfk9ShxVNTjL+0dLjyOAZZOicFjYlVOu3iMeZK3lU3/+iNyyOj53dgo3LU1ienxo+4e2uuZW3kstJL+8vr2i4KPMEhqaHby+7zgTIsb0qTdndGggiyZGsi61iHt6uXpXZX0zfj6mR1Ni3Hk/zdnDZvWsnv0cnT89ht+vy2BjRglXzR/fp3N6s7cOnGRXTjkPfuqsPv+fDiVjDL/41Flc/rsKvv7sHt74+rkEB5wZR2FVA+8cOsnbhwrZklVKq8OSEB7ETUuSuGxOAstSojTTY5AE+fuyfHI0bx44wZsHTjB7XDifPzeF86bGsmRS5JCvtijdG36vFCPItmNlRIcEMCXWOZ/2qvnj+flbqaSdrOr0mPcOF/HjNw4TFx7IlfNG3h8yERGRwbbhSBEJ4UHcsmIi69KK2JtXwcopvZ+K09GWrFJ8DCybHMWYAN8zkkMxoYFcOieBxzdnU9PYQmg3H96qXBVHo6XHETibr/r6GHZklylx5EF1Ta0cK6nl25dOd9uodvHESMCZsEuKCqa0ppHs0jruODeFHTnlnNOP343Vs+L45dp0TlY2kDC2+8bG9U2t/G1jFn/54Cizx4Xzr7tW9qkqYV1aERMixjAjPqxH+y9IimTsGH82pBd7beJo7cGTxIcHstD1fPVUY0srv1ibysyEMG5YnDRAoxt4EcEB/Pam+dzy6DZ+8sZhfn79PMC5Qtrbh06y9tBJ9uRWADA5JoQ7V03msjkJzJsw1mt7OY10P7lmDgcLqlg+OUoVXsOQEkdDaPuxMpalRJ3yB3BGQhjpJ903JAQ4UFDZfqwSRyIiIv3T0upgY0YJn5g7jsUTndNvduWU9T9xdLSEsyaM7TLRc9HMOP76YRYbjxR321epapT1OAIICfRj7vhwdhwrH+qhjChlrj5GcZ2sSDUjIYyQAF925ZRz7cIJ7HZ9+L5sbgLfv3J2v5pbXzwrnl+uTWddWiG3LE/udD+Hw/L6vuM8uDaNE5UNzBkfzs6cct5LLeKS2fG9OmdDcyubMkq4YXFij5NOvj6G86bF8MGRYhwO63WJhrqmFu55fg9xYUGs+3/ntzf7bvPnDUfx9zXccd7kM4598qMc8srqeeoLy/D1srh66+wpMXxp1RT+8sFRHA7Yl1/RPu147oRw/t8l07l8bgJT40I1DcoLJEeHkBytBuTDVbe1ecaYIGPMdmPMPmPMIWPMj1zbVxtjdhtj9hpjNhljprq2BxpjnjfGZBpjthljJnV4rPtc29ONMZcNVFDDwfGKevLL61l22hzxmePCOVpcQ3Orw+1xh45/nDgSERGR/lmXVkR1QwsXz45nbLA/0+ND2ZHdv0RFXVMLe/MqWNFN8mlJsrOq4b3Uom4fs6reNVVtFFUcASydFMXe/AoaW1qHeigjRlsD7OhOmkT7+hgWToxkV47z92B3bjl+PqZ9qfb+fACfFhfKxKhg1nXxM787t5zr/vwR9zy/l+jQAJ6/cwWvfuUcUmJC+PXb6WespNVdImtrVin1za09nqbW5oIZcZTUNHL4ROczAYbK+rQiGpod5JbV8eqeM1dm/sfmY/zsrVT25VWcsr2stonfr8/gwhmxnDctdrCGO6C+dcl05ieO5YVdeYQH+fODK2ez8TsX8sbXzuNrq6cxLT5MSSMRD+jJpM5G4CJr7XxgAXC5MWYF8GfgFmvtAuCfwPdd+38BKLfWTgUeAh4EMMbMBtYAc4DLgT8ZY0btZMZ3XA0yl046LXGUEEZzqyWruPaMY6y1HCioxNfHkF5YTUVd06CMVUREZKR6emsO48cGceEM54eoRRMj26t7+2pntrPh59lTYrrcz8/XhwtmxLIhvYjWbpaV/rjiaHQViy9NiaKpxcH+/P49J/KxclfiKLKL1cUWJ0eSdrKKmsYWduWUM2fCWI/0IDHGsHpWHJszS6hvOjMZmFtax02PbOFkZT2/vnE+r3/lXJZPjsbf14dvXjKd9MJq7nhyJ09vzaHFdZH1+68e5Lo/baakptHtOdenFTHG37fXK8GdP935mrAhvfvE7mB768AJYkIDmTM+nIffz2z/vwBncqiouhGHhXtfPnDKxejfr8ugrqmV731i1lAMe0AE+Pnw3J0r2f39S3jhrpV84dyUPvXgEpGudZs4sk41rm/9XV/W9dW2huxY4Ljr9jXAE67bLwKrjTPNew3wnLW20Vp7DMgElnkkimEms6iaB9ems3JyNHPGn7oM74wE59xrd32OCirqqahr5hNnjcNa5xtTERER6Zus4ho2ZpTwX8sntjdIjQ0LpKKu6Yyqht7YklWKn49hSXL3vUdWz4qntLaJvadVBpyusr4Zf1/DmFHWQLTtApsqrT2nu4ojcCaOHBbe3H+c/fkVLJroueXaL5kVT2OLg6e2Zp9x3ws782h1WF758jncsDjxlCliV541js+fk0LaiSq+/+pBNqQXY63lrQMn2JNbwU2PbKGwquGUx7PWsi61iHOnxfQ68RUb5kzMbMos6VOcA6WuqYX1aUVcPjeeb6yeRk5pHa/tPd5+f9tniFtXTCT1RBV/2XAUgMyiGp7emsOapUlM62Gvp+FiTIBvl4lQEem/HrWRN8b4GmP2AkXAu9babcAdwFvGmHzgNuAXrt0nAHkA1toWoBKI7rjdJd+17fRz3WmM2WmM2VlcXNy3qLxYQ3MrX/3nHoIDfPndmgVnlE5OjgnF39e0z8/t6KDrCuityycS4OvDdg8tGSwiIjIaPb01F39fw6eXftwgNjzIH4eF2qaWPj/ulqOlLEiK6NFqRedPj8XXx7AutbDL/arqmwkP8h91Uy6iQgKYGhfKDr3n8ZiyWmdlTlQXH7SXpUQxMyGM7750gIZmB4t7kATtqRWTo7l0djw/eyuNl3blt29vdVhe3JXPqumxjI8Yc8ZxPj6G/71qNuu/fQGBfj5sySrlaHEt5XXN3LQkiZOVDXz6kS3kl9e1H5NeWE1BRT2rZ/atufpZE8aSUVjT/Y6D6P0051LynzxrPJfMjmf2uFOrjtJOOD9DfH31NK6aP57frcvgPwdOcOeTOwkO8OWbl/RuRTsREehh4sha2+qakpYILDPGzAW+CXzCWpsI/AP4rWt3d+9obBfbTz/XX621S6y1S2JjR8bc245+8sZh0k5W85tPzyfeTVPCAD8fpsSGum2Q3TZNbX5SBAuSItimq28iIiJ9cryinud25HLF3HHEhX389zgsyJnsqW7oW+KouqGZAwWVPW6uPXaMP0snRXbZ8wWgqqFlVDXG7mjppCh2ZZd3O51Peqas1lm91tVKfkH+vrzy5XP41KJEwgL9zujJ2R8+PoY//NdCzp0aw7df3MeDa9NoanHw4ZFiTlY1cNOSrlf6CvL3ZdHESLZmlbIrx/le+IurJvPUHcspq23ipke2klPqbPnwziFnQvbCPiaOpsaFUlrb1N5QfLA98MZh7n/9EAdcUzUbW1r5ywdHiQ0LbF9g5+urp3GspJbX9zmrjtJOVhEdEkBsaCA/vW4uEyLGcPczuzlZ1cA/PrdUq1mJSJ/0KHHUxlpbAWwArgDmuyqPAJ4HznbdzgeSAIwxfjinsZV13O6SyMfT20aFtw6c4JltuXxp1eQul5WdmRBGmptGfAcLqpgWF0qQvy8rJkdxsKCSzCLvugoiIiIyHPzo34dwWMt/XzbjlO1tyZm2nkK9tSO7jFaHZWUv+qlcPCue9MJq8srqOt3HWXE0uvobtVmWEkl1Y4vbafzSe2W1jUSFBHRbvTYmwJfffHo+e/73klOSq54Q6OfLXz+zmDVLk/jzhqOc98v1/M8rB4gOCWD1rO5XTVs5JZrDJ6pYl1pEZLA/U2JDWDQxkme/uIK6phZu/MsW/rQhk9+vy+DcqTFuL9b2xNS4UIAheb+dVVzDo5uO8fhH2Vz18Ca+8sxuvvfyQQ4UVPLAtXPbV0S7dHY8MxPCeHh9Jq0OS/rJamYkOBtChwf58/B/LWRe4lgeu30pi5M9lwAUkdGlJ6uqxRpjIly3xwAXA6nAWGNMW63jJa5tAK8Dt7tu3wCst87lDl4H1rhWXUsBpgHbPRaJl8srq+O7L+1nQVIE3z7tTerpZiSEc7yygR/9+xD3v36IH7x6kO+9coDdOeXMda1ocdvKSYQE+PLD1w/2a1lUERGR0WZ9WiFvHyrk66unndFEtb8VRx9llhLg58OiXkztafugvD6t86qjqobmUVtxtCzFmYTboUprjyirbSIqpOdVJ36+vbrO3GPBAX78/Pp5PHb7EpalRDM2OICvXDiVAL/uz7dicjTWwruphSxOjmxPgs2dMJbn7lyJw8Iv16azLCWKP9+6qM9jbOsFlFF05kyAgfbm/hMAvH3PKr51yXTePVzIS7vz+dL5k7lsTkL7fj4+hnsunkZWSS2v7S0gvbCamQkf91CdlxjB6189t8dVkCIi7vTk0tU44AnXCmg+wAvW2jeMMV8EXjLGOIBy4POu/R8DnjLGZOKsNFoDYK09ZIx5ATgMtMD/Z+++w9s6y/+Pv4+GJctL3nvEI3vv2bRNRzropNAWaAtltJSy+QIFWqD0BxQou0CBMgp073SPNM1Os4fjJHa8tyVbHpKsdX5/SHbsesRDthz7fl1XriZHR+c8SpzG+uh+7pu7VFWdErNV3V4fdz9+AIDf37QI/Vn+AV6TH09MuJ6nPqhEo1HQaRS0GoVIo47L5vr/oUiMMvCtS2fwgxeP8fLhWq5akDbmr0MIIYQ41zlcXu598RgFSZF8dm1un8ejAuPu20ZYcbTztIXFWeZhNeKdlhBBbmIEbx+v59bVOf2eY3O4SYvp2/dlKkg3h5NuDmdPmZXb1kwL9XLOef7gaOKEkBtmJQ+pyqinBZkxGHQaOj2+PlU0M1KieOaOVbxVWM8tq7Mx6EbeUD4txogpTBuSPkebDteyLCeWGSlRzEiJ4rK5KWw91cQtq7L7nHvJ7BRmpkTxwCvHcbp9zEydXM2vhRChd9bgSFXVw8Cifo4/Dzzfz3EncMMA13oAeGD4yzy3/fKNExysbOHhTywe0njI+RlmDt13yVnPu3lFNk/ureTB14u4fG7KmH0iJIQQQkwWv3/3FFXNDp74/Mp+Kxu6toO1OoZfcdRid1FY28rXLhp+89kNM5P4145y2js9/faeaXVM3R5HAMtyYtlWbEFV1SnXIDzYrB0u5sUGb0paKBh0WpZkx7KjxNJv4+6chAg+d17fYHi4FEUhPymSksbxDY5O1bdxor6NH101p/tYQXLUgNPQNBp/r6Mv/nc/4G97IYQQwSRJwziIMOi4ZVU2l89LDep1tRqFL19YQFUixOh/AAAgAElEQVSzg1eP1gX12kIIIcRkU9zQxl+3nub6xRmsHKAH0WgqjnadtqKqjGhLyIZZybi8Prae7H+irH+r2tTscQSwbFocTe2dlFkG7gMlhsbS4SJ+Eowu3zArmViTnvkZMWN6n/zEyHGvONp0uBZFgcvmpZz95ICNc1KYkRyFRoGCJAmOhBDBJcHROPjyhoJenxgE00WzkslNjOCR90uk15EQQggxAFVV+d7zRzGF6bjn8pkDntfV46h1BD2OdpY0Ea7XsiBj+NUcS7NjiQnX83Y/09Wcbi8uj49o49StOFqe49+OJH2ORsft9dHm9BBrOveDo0+vzmH7dy4c1rbQkchPjqSu1Tni7avDpaoqmw7XsGJa3LCakms0Cg9+dD4/vGoO4WFj+3sihJh6JDgaJ2NVVq3RKHxuXS5Hq1vZWWIZk3sIIYQQ57rn9lezu9TKdy6bSfwg46iNei1hOs2gU9X++v5p/ri5uM/xnactLM2JHVJz3w/TaTWcPyOR90409Bk737WWqbxVLT8pkliTnj1lEhyNRnNgrHxc5LkfHGk0Cqawsa/C66reGa/JakV1bZQ0dnDl/OH3L12QaeaWVTnBX5QQYsqT4GgSuHZROmaTnmf2V4V6KUIIIcSE097p4f+9epzFWWY+vjTzrOdHG3UDTlWzuzz85u2TPLy5GJfH1328sa2Tk/Xto5pctGFWMpYOFwcrW3od7+q31NV/aSpSFIWlOXF8IMHRqFi6gqNJUHE0XvKTIgE4NU7B0SuHa9EodA/EEUKIiUCCo0nAqNeyriCRbaeaZLuaEEII8SFFta1YOlx88fx8NJqzVwBHG/W0OvqvOHr9aB0dLi8dLm+vEGPXaX/V7+q8hBGvc31BIlqNwjvH6wHweH08vqeC+lanf11TuOII/NvVyi12GgK/H8HwwoFq9kyh7W/dFUeToMfReMmKMxGu13KgouXsJ49S1za11XkJg1ZGCiHEeJPgaJJYV5BAQ1snJ+rbQr0UIYQQYkKpsfmDhqz4s082BX+fo4Eqjp7ZV0W6OZwwnYZ3i870IzpU2UKYTsOctOgRrzPGpGdJdixbTzUBsLW4ie8+d4T7NxX6H5/iwdGyaf4+R8Harlbc0M43nj7EI++XBOV654KuiqP4SbBVbbxoNQob56aw6XANTrd3TO91rKaVMoudK+cHd6COEEKMlgRHk8S6Av8nnO8PMI1FCCGEmKpqWxwApMYMrdFslFHfbyPc6hYHO09buGGpfyrb5hNngqOjNTZmpUaj147uW6sl2bEcr23F6fZyMFDhUFTn/1BoKjfHBpiTFo0pTBu0Btm/fOMEXp9KQ1tnUK53Lmi2+4OjydAcezzdsCSDNqeHN46N7RTjlw/XoAsEVUIIMZFIcDRJpMaEMz05svtTSiGEEGIqsXa4+MJje2nsJwSotTmJMuiIGmLwEh2u63eq2vP7q1BVuH5xBhfMSOR0Ywfllg58PpVj1a3MHUW1UZeFmWY8PpVjNTYOVbWQFWfq3lYUHT51exwB6LUaFmfFsqesedDz3i2q55Jfb8E2wHZDgP0Vzbx+rI4wnabfr5nJytLeFRxN7RByuFbmxpMRG87Te8eun6iqqrxyuJa1BQmYJdgTQkwwEhxNIusKEtldah3zMlohhBBiotlTauGNY/VsLuo7zr6mxUGqeehjraMMfSuOVFXl2f3VrJgWR2aciQtmJAHwzvEGKpvttHV6mJceM7oXASzKNANwoKKFQ5UtrMqN54Fr5rI0O1YaGgPLcuIoqmvtDoVUVe3T3/FQpY2T9e089UHlgNd5ck8l0UYdNy/PorGtE59vavSItHa4MJv06EZZGTfVaDQKH12SwfaSJqqa7WNyj0NVNqqaHVwxT7apCSEmHvlXYxJZV5CAy+Nj9xRq8iiEEEIAVFj9b+YOV/dtYFtrc5IaEz7ka0UZdd2TzLrsr2imtKmD65dkAJCTEMGM5ChePVLL0epWAOYGIThKijaSFmPk5cO1NNvdLMg0c9m8VJ65c7W82QeWTYtFVWFfuf97nS/97wB3P36g1zldodI/d5Th8fr6XAOgqsVOXlIk2fEmPD6VlkGqkyain71WxIsHq4f9PKvdJQHkCF2/OANVhWf3Df/3fSg2HaohTKvhkjmyTU0IMfHIdyCTyIpp8YTpNGyVPkdCCCGmmEqrv4/RkSpbn8dqbQ7ShlFxFB2ux+H24u4ROjyzr5pwvZbLe1QDXLUwjb3l/i1Peq1CQXLkKF7BGQuzzByq9AdgCzJHH0ZNJosyY9FrFfaUNtPp8fJOUX2fD8y6gqPqFgdvHKvv9zq1NidpMeEkRvknVzW0BW9S23j47+5y/vBu8bCf19jWKY2xRygzzsTqvHie2V8Z9Ao1n0/l1SO1nDc9Yco3wRdCTEwSHE0i4WFalufE8f4pCY6EEEJMLZWB7SPHa9twec4EPp0eL03trmFXHAG0B/ocOd1eNh2uYePcFCINZ/oMXbUgDYCXD9UwPTkKg0476tcB/j5HAEa9hunJUUG55mQRHqZlbnoMH5RZOVRpw+n20djWiTUwLQygxe5idmo0WXEm/r7tdJ9rqKpKbYuTlBgjSVH+QPFc6nPU6fHS5vRwqqGd4ob2IT9PVVVO1LVRIF9TI/axpZlUWh1Br+7fVtxEjc3JFTJNTQgxQUlwNMmcNz2Bk/Xt1NnOrU/OhBBCiNGosNox6DS4vD5O1rd1H+/693CoE9WA7ibarYE+R28V1tPm9PDRwDa1LplxJpZmxwIwNy14lUELM89cc7RT2iaj5TlxHK5q4b0eU+16/pm3ONzER4bxmTU57K9oYX9F72barQ4PDreX1BjjmYqj1nMnOGruOLOtbjhTvqpbHNgcbmanjr6J+1R16ZwUogw6nt43cP+s4fL5VH7+ehHp5nAumyvBkRBiYpLvRiaZdQWJAGyVqiMhhBBThM+nUtXs6G5YfbjHdrWaFn9wlGYeesVRdKDiqC1QcfTMvirSYoysyo3vc+7Vi9IBmJsevDfj89JjCNNpWBIIpURvy3LicHtV/rOrnKRA8NMzOLLZ3cSE67lhaSZRRh1/31ba6/m1rf5tjakx4d3Pb2w/d4KjpsBaNQq8drR2yM8rrPH34podhOl/U1V4mJaPLEzj1SO1fRron82Jujau+eP2PtsiXzhYzbGaVv5v4wyM+uBULQohRLBJcDTJzEyJIjHKwPunmkK9FCGEEGJcNLZ34vL4WJ0fT0y4niM9GmTX2rpCghFUHDnc1Lc62XqqkWsXp6PRKH3OvXphGjcsyeDSIDa0DQ/T8vwXV3PXhflBu+ZksjTHH6i1Oj1cOT+NaKOud3DkcGM26Ykw6LhpeRavH62jusXR/XhtIExMiTESYdBhCtOeUxVHXdvyNsxK5mh1KxWWoU35KqxtRVH83yuKkbthSQZOt49XDg89tAP4y/slHKxs4e3CM5VyNrubX7xxgnnpMXxkflqwlyqEEEEjwdEkoygK6woS2HaqccqMlhVCCDG1dU1Uy4wzMT8jplfFUW33VrVhVByF+yuOWp0eXjhQjU+F6xZn9H+uUc8vblhAUvTQg6mhmJMWQ7RRmuT2x2wKY0agT8+qvHimJ0dxss7f60dV/RPSuhoM37o6B4B/7Sjrfn7X10RXw/SkKMM5VXHUFRx9cmU2eq3CjY/s5J3j/TcB76mwppVpCRGYwnRnPVcMbGGmmfykSJ7eVzXk51g7XGwKBE1duwJ8PpWvPnmApvZOfnz1nH6DaSGEmCgkOJqEzitIpNnu5ligJFkIIYSYzCoDwVFWnIkFGWaK6tr4z65yVFWlpsVBrElPeNjQt4BE9+hx9Oz+KhZnmclLDM7ENBEcK3Lj0GoUlk+LY3pKFCfq21BVlfZOD16fijncPzks3RzOxrkpPL6ngo5O/9bDWpsDjQKJkf5taolRBhrPoalqXVvVFmaYeeLzK4k06vjsv/dS3NA26PMKa1ulv1EQKIrCx5ZmsK+8ecjNyZ/aW4nL42NJdizbi5vweH08/F4xm080cu+Vs1mUJdtShRATmwRHk9DaggQAma4mhBBiSqi0+rchpZvD+czaaazOi+f7Lxzlzv/sp8JqH1a1EZyZqrazxMLJ+nauX9J/tZEInS9vKOA/t68gJlzPjOQobA43DW2dtNj9fWdiTGeqtW5fO402p4en9/obGtfanCRHG9EFGo8nRhloOIemqlk7XOg0CtHhOpZkx/HY7StQVXizcOCqI5vdTVWzQ/obBck1i9LRahSeGULVkdfn78e1MjeO21bn0Or08PqxOn73bjFXzE/lkyuzx2HFQggxOhIcTUIJkQbmpEXz/kkJjoQQQkx+FVY7KdFGjHotcRFh/OvTy7nn8pm8fqyOraeaurckDVWkwR8cbTpcQ5hOw5XSe2TCSYg0sCrP36y8INlfDXayvg2bwx8cmcPPBEeLs2JZnGXmHzvK8PpUam0OUnr0vEqKMtIYxOBoR0kTf9lSgneMWgZY2l3ERYShKP6tTcnRRualx/DO8YYBn1NYG2iMLRVHQZEUZWT99EReOVLT5zGP19fr11tONlDV7OBTK3NYk5+AosC3nzkMwPcun9X95yiEEBOZBEeT1LqCRPaVN9MeKMsWQgghJqvKZjuZcWeqijQahc+fl8cD184FICPWNKzr6bQaIsK0uL0qF89O7u6XIyamrn5HJ+rauiuOzKawXufcvjaXcoudd4saqLU5ezVLT4wy0Ob04HR7+73+o9tKOVU/+Dawnh568yQ/fa2ILz9+gE5P/9ccDUuHPzjq6cKZSeyvaO7uf/RhByv9DePnpMUEfT1T1eq8eCqtDhpaz2xzfO9EA/N/9GavY//e6Z/+d8mcZOIiwpiXHkOHy8tn1kwb1rRHIYQIJQmOJqnzpifg8ansKrGEeilCCCHEmKqy2snsJxz6xIpsnr5jFXddMPzpZF2T1T4q29QmvPhIA2aTntKmju6Kow+HfZfOSSYxysCTH1RQ2+LstX0xMcrf66i/qqOm9k5+vKmQbz1zGFU9ewVRR6eHg5UtzEyJ4pUjtdy/qXA0L61flo5OEgL9mbpcNCsZVYXNRX2rjqqa7Tz8XjHLcmK7X6sYvSXZ/r5Ee8ubu49tL27C7vKyNTDduNzSwZaTjdy0PAt9YGvkxrkpJEcbuPP8vPFftBBCjJAER5PUkuxYwvXa7skNQgghxGTU6fFS2+okM67/qqJlOXEjerMcHa4jMcrAuvyE0S5RjIPsOBMVVjstDn/FjdnUOzjSaTVcvziDd4oacLi9fSqOABr6aZB9PLDF62Bly6BbwbrsKbPi8al8/4rZfHxpJs/uq6bV6R7x6+qPtZ+Kozlp0SRFGXjuQBXvFtXzblE9m4sa2Hyiga89eRBVhV/dsDCo65jq5qTFYNBp2Ft2JjjqGkyz87T/g9v/7q5AoyjcvCKr+5w71+ex7dsXSiWjEOKcIvM4JymDTsvK3DjeD3ziIYQQQkxGNS1OVJUBg6ORumN9HuF6bXcDZTGxZcaZOFJtO9Mcu5835R9bmsGft5QA9Ko4Shqk4qgrOEqLMfLLN09w4cykQcem7yyxEKbVsDQnluhwHU/ureTFA9V8alXOiF/bh1naXcRH9g6ONBqFS+ek8NiucrYX9602f+hjC8iKD+7fkakuTKdhYaaZveVWAFRV7e4ltbPEgtPt5am9lVw6J5nk6DNBpaIo6LXS10gIcW6R4GgSO296IptfLqTSag/6N9RCCCHERFBptQOQGRvcXiHXLZYtaueSrDgTrx+tw9LuwqjXYNRr+5yTmxjJ8pw49pRZezXHTgm8qX//VBMb56b2ek5hTSupMUa+tXEGX3vyELtLrd1NufuzvbiJxdlmjHot89JjmJMWzX93V/DJldlBaYLsdHtp7/QQ/6GKI4DvXTGLG5Zm0NWTu2trXUy4ntzEyFHfW/S1NCeWP285jd3lodnupsXuZnpyJCfr23l4czEtdjefWpkT6mUKIcSoycdok9i6gkQA3pftakIIISapikBwJNUUU1t2vAmPT+V4bSvm8L6hSpdPr8nBFKYlNyGi+1h8pIHbVufwv90VPLqttNf5hbWtzEqNZmWuPywqaWwf8NrNHS4Ka1tZneff3qgoCjctz6Koro39Fc0DPm84uppfx0f23X5p1GuZn2FmYab/x6KsWBZlxUpoNIaWZsfh9akcrGzhWLUNgNvXTgPgj++VUJAUycrcuFAuUQghgkKCo0ksLzGCdHM4W0824fWpPL6nghZ7/9M2hBBCiHNRZbOdMK2G5Cjj2U8Wk1ZXZfXRaluf/kY9XTYvlUP3XULshyp2fnDlbC6Zncz9rxTy2pFawF/dU9LYwezUaJKjjITpNJRbOga89paTjagqrMk/U5F0zaJ0EqMMfOOpQ92Nu0ejKzj6cI8jERqLs/wNsveUWimsbUVR4Mr5aSREhuH1qXxqVXAqzYQQItRkq9okpigK6woSeOVILf/YXspPXjlOq8PNF9bLFAchhBCTQ5XVQXps+KB9Z8TklxUIjto6PUSfpemwvp++VVqNwu9uWsTNf93FV588SFK0gTCtFq9PZVZqNBqNQnaciXKLvd9rdnR6+MUbJ8hPimRBhrn7eKRBx58+sZib/rqLLzy2l2U5cVg6XFjbXVg7XLQ63dxz+SzOm544pNfZ1O7vw9TfVjUx/mJMelbmxvGvHWUUJEeRmxBBhEHHmvwE3i6s59pF6aFeohBCBIVUHE1y6woSaXN6+OlrRYB/KogQQggxWVRIHz+Bv9l1V8Nh8winVRn1Wv526zLSzOHc/q+9bDpSA8DstGgAsuMjBgyOfv3WSapbHPz0unl9GqovzYnjx1fP5YOyZv6wuZjXj9ZR3NgOClQ3O3jyg8ohr3GwrWoiNO77yBxanR72lFqZnRYD+CvYnvviGqKMMjlNCDE5SMXRJLcmPx6NAmFaDXOzoiU4EkIIMalUNtuZnxET6mWIENNqFDJiTZQ2dQy6Ve1s4iLC+Oenl3Hdwzv4y5bTmMK0ZAeCyex4E9uKG1FVtdf2o6PVNh7dXspNy7NYltN/P5ublmdx9cI0DDot2h7Vcd98+hBvH6/H61N7HR+IpV22qk00s1Kj+cyaHP66tZQ5gZAxIdJAgoR7QohJRCqOJjmzKYw7z8/jp9fNY+PcVGptTupbnaFelhBCCDFqrU7/FCOpOBJwps+R2TS6UCU7PoK/37YMo17TvU0NICfehNPto6Gts/tcj9fHd587Qnykge9cNnPQ65rCdH3CoXUFCbTY3RwNNFY+G0uHC71WIdoon/1OJF+5aDo3r8jiinmpZz9ZCCHOQWcNjhRFMSqKskdRlEOKohxTFOVHgeOKoigPKIpyUlGU44qifLnH8d8pilKsKMphRVEW97jWrYqinAr8uHXsXpbo6VuXzuSaRekszPTvuT9Y2UKr082p+rYQr0wIIYQYucquiWoSHAnorgyKGeFWtZ4WZpp55o7V/Oy6ed3HsuL9k9h6blf7544yjlTbuO8js0d03zX5/gls24qbhnR+fauTuIgwabg8wUQadPy/a+dJiC2EmLSGUnHUCVyoquoCYCGwUVGUlcBtQCYwU1XVWcATgfMvAwoCPz4P/AlAUZQ44D5gBbAcuE9RlNjgvRRxNnPSotFrFQ5WtvDZf+7lit9v6/6mWwghhDjXVFodAGTGyps1cSZAHM1WtZ7mpsdQkBzV/euceP/1ywKT1apbHDz01kkunJk04kqThEgDs1Ojef9k41nP3Vli4aVDNazOSxjRvYQQQoiROmtwpPq1B36pD/xQgTuBH6uq6guc1xA452rg34Hn7QLMiqKkApcCb6mqalVVtRl4C9gY3JcjBmPUa5mVGs1/d5Wzp8yKy+PjwTdOhHpZQgghxIhUNUvFkTgjM4gVR/1JM4ej1SiUWzpQVZV7XziKqsKPr54zqgqgddMT2F/RzKHKFhwub7/n1NocfOl/+8mON/Hjq+eM+F5CCCHESAypx5GiKFpFUQ4CDfjDn91AHvBxRVH2KorymqIoBYHT04Ge4yGqAscGOv7he30+cM29jY1n//RFDM+CDDOtTg8zU6K464I8Xj5Uw77y5lAvSwghhBi2CqudKKOOmCBVmIhz2+JsM7NSo5mXPjbN0vVaDRmx4ZRb7Lx6pI53ihr4xiXTyRhlxduGmcm4vSpX/3E76x58F6e7d3jU6fFyx3/243R7eeRTS2RSlxBCiHE3pOBIVVWvqqoLgQxguaIocwED4FRVdSnwV+DRwOn9feSiDnL8w/d6RFXVpaqqLk1MTBzK8sQwrMj1T/v4wZWz+eL5+SRFGbh/UyGq2uePQgghhJjQKq122aYmuiVFGXntK+vIDvQiGgvZ8RF8UGbl/545xPyMGG5bnTPqay6fFsfbX1/PNy+ZTlO7i71lvT/Q++FLhRyqbOFXH1tAflLUAFcRQgghxs6wpqqpqtoCvId/i1kV8GzgoeeB+YGfV+HvfdQlA6gZ5LgYR5fPTeX9b13AmvwEIgw6vnnpDA5WtvDy4dpQLy3oVFWVQEwIISaxCqtdtqmJcZUdZ6K+tROzKYxHPrUUnTY4A4rzkyL5zNpphGk1bDnZ0H38iT0VPL6ngjvPz2PjXJnYJYQQIjSGMlUtUVEUc+Dn4cBFQBHwAnBh4LT1wMnAz18CbglMV1sJ2FRVrQXeAC5RFCU20BT7ksAxMY40GoWs+DPfZF+/OIPZqdH8/LWiPqXR5zKXx8fKn77DFb/bxgsHqkO9HCGEEEGmqipVzQ4y48JDvRQxhazKiycn3sRjty8nJcYY1GubwnQsmxbL+yf9E9YOVrZw74vHWJufwDcvmRHUewkhhBDDMZSPSVKBzYqiHAY+wN/jaBPwM+B6RVGOAD8FPhs4/1XgNFCMfwvbFwFUVbUC9weu8QH+xtrWIL4WMQJajcL3r5xFdYuDR7eXhno5QVNm6aC+tZMam4OvPnmQHSVDG3MrhBDi3NDY1kmnxyfjr8W4unxeKu996wJyEyPH5Prrpydyor6No9U27vzPPhKjDPz+pkVoNSNvvi2EEEKM1lCmqh1WVXWRqqrzVVWdq6rqjwPHW1RVvUJV1Xmqqq5SVfVQ4LiqqupdqqrmBR7b2+Naj6qqmh/48Y+xe1liOFbnJXDx7GQe3lxCY1tnqJcTFMUN/kGAf/nkEhQF9pRKRimEEJNJhdU/UU2CIzGZrJ+eBMAn/rYba4eLv3xqCbERYSFelRBCiKkuOBuzxTnvu5fNxOn28uu3T5795HPAqfp2FAXmZ5iZkRzFgYqWUC9JCCFEEFU2B4IjaY4tJpHpyZGkRBuxOdw8cO085o7RhDghhBBiOCQ4EgDkJkbyqVXZPLGngtKmjlAvZ9RONbSRERtOeJiWRVlmDla24PNJo2whhJgsKq0OADJipceRmDwUReHrF0/n2xtn8tElGaFejhBCCAFIcCR6+MJ5efhUePXIuT9hrbihnfxA/4FFmbHYHG5KLed+ICaEEMKvwmonOdqAUa8N9VKECKqPLcvkzvPzQr0MIYQQopsER6JbSoyRBRkxvFVYH+qljIrXp3K6qYOC5CgAFmWZAWS7mhBCTCKVVrtsUxNCCCGEGAcSHIleLp6dzMHKFhpanaFeyohVWu24PD7yk/wVR3mJkUQZdByoaA7xyoQQQgRLVbNDGmMLIYQQQowDCY5ELxfPTgHgrePnbtXRqcBEta7gSKNRWJhlZr9UHAkhxKTg8viosUlwJIQQQggxHiQ4Er1MT44kK850Tm9XO9XQBpwJjgCWZMdyoq6V4sBjQgghzl01LQ5UFTKlMbYQQgghxJiT4Ej0oigKG2YlsaPYgsfrC/VyRqS4oZ3kaAPRRn33sU+uzCbSoOPeF4+hqjJdTQghzmWVzXYAsqTiSAghhBBizElwJPqYnhyFy+uj7hzsc9TQ5mTrqSZmpET3Op4QaeBbG2eyo8TCf3aV43R7Q7RCIYQQo1Vh9QdHslVNCCGEEGLs6UK9ADHxdE2pqWp2kHEOTaxxur184bF9tDnd/N+lM/o8fvPyLJ7ZV8UPXjzGjzcVMicthiXZsSzOiiUlxsDOEgvpseFcuygjBKsXQggxVJVWB3qtQnK0MdRLEUIIIYSY9CQ4En1kBHpGVFrtrMyN7z5+sLKFBRkxKIoSqqUNSFVV7nnuCAcqWvjTJxYzNz2mzzlajcLjn1vB9mIL+8qb2V/ezH92lfP3baXd5yREhklwJIQQE1xNi4PUmHC0mon375EQQgghxGQjwZHoI9VsRFH8FUddjlbbuOaP2/nzJxezcW5qCFfXvz9vOc1zB6r5+sXTuWzewOszhem4eHYyF89OBvyTeY7XtlJrc7C3rJm/bSvF7vJgCpO/GkIIMVHVtDhIM0u1kRBCCCHEeJAeR6IPg05LSrSxV3BUGegnseVkY6iWNaC3Cut58I0iPrIgjbsvzB/Wc8N0GhZkmtk4N5V5Gf4qpZ6vWwghxMRT0+Ig3XzubKUWQgghhDiXSXAk+pURG949tQbobpS9vdgSqiX1q6iula8+cYB56TH84qPzR7WNrqufU1dIJoQQYuLxBIY3pEvFkRBCCCHEuJDgSPQrI9ZEdY/Km67gqMJqp8IyNsHK1lONfOl/+6lqHtr1XR4fn/v3XiKNOv56y1KMeu2o7p8Zd6a3kxBCiImpvq0Tnwpp5vBQL0UIIYQQYkqQ4Ej0KzM2nFqbA7fXB0BDaydhOv+Xy/aSpqDfr6ypgy/+dz+bDtdyxe+28c7x+rM+p6SxnUqrg+9cNjMok3USIw0Y9RoqZauaEEJMWDUt/v9HS3AkhBBCCDE+JDgS/cqINeFTobbFX2lUZ3MyLz2G5GgD24qDGxw53V7u+M8+NIrCf25fQbo5nNv/tZefvnq8O7jqT7mlA4CCpKigrENRFDJjTVJxJIQQE5gER0IIIYQQ40uCI65z248AACAASURBVNGvjMC2ra5tY/WtTlKijazJT2BHcRM+nxq0e+0ta6aoro2fXDOXtQUJPPfF1XxiRRZ/ef80Nz2yi1pb/xVAZYEtc1nxwWuQmhlnkoojIYSYwKq7gyPpcSSEEEIIMR4kOBL9yuxqFN0jOEqONrI2P4Fmu5vC2tag3avrHouzYwEw6rU8cO08fnvjQo7XtnL5b7dS3NDe53nllg7iI8KINuqDtpbM2HCqrHZUNXjBmBBCiOCpbnYQa9JjCtOFeilCCCGEEFOCBEeiXykxRjSKfzR9m9NNh8tLSoyBNfkJAOwYRZ8jp9vLt585zJ+3lAD+NwFajUJylKHXeVcvTOelu9fidPv429bTfa5T1mQnO4jVRuCvOGrr9GBzuIN6XSGEEMFR0+KQbWpCCCGEEONIgiPRL71WQ2pMOJVWO/WtnQAkRxtJjjZSkBTJtmLLiK7b6nRzy9/38OTeSp7eWwn4t8OlxhjRaft+OeYlRvKRBam8dKiGNmfvMKfc0kFOfMSI1jGQjK5KK6tsVxNCiImopsVJugRHQgghhBDjRoIjMaDseBMljR3Ut/obZHdNLluTn8CeUgudHu+wr/mbt06xv6KZBZlmKqx2PF4fVc0OMmIHfhNw0/Is7C4vLx6s6T7mdHupsTnJDnJwlBno7dS1fU4IIcTEIhVHQgghhBDjS4IjMaCl2bEcq7F19xdK6REcOd0+9pe3DOt6qqry9vF6zpueyCdWZOH2qlQ1O6hqdpBuHnjL2cJMM7NSo/nf7oru3kNdk89yEoK/VQ2gQiarCSHEhGHtcHHro3t4Yk8FbZ0eqTgSQgghhBhHEhyJAa3Mi8enwsuH/JU+XRVHK3Lj0GoUthcPr89RaVMHFVY7F8xIJC/RXylUVNdGfZtz0IojRVG4eUUWhbWt7Dzt3yLXNVEt2BVH0UY9ZpO+O5gSQggRGh+UWfnj5mIcLi/ffPoQW0428p3njgBIxZEQQgghxDiS4EgMaHFWLGE6DXvLm4k26ggP0wL+cGVBRgzbh9kg+92iBgDOn5HEtIRIALYXN6GqDBocAdywJIOkKAO/efsUqqpS1tQBQE6Qm2MDpJvDqWmRHkcTjcfr40iVLdTLEEKMk4fePMkv3jjBmp+/y7tFDXx740yW5finb57t3wwhhBBCCBE8EhyJARn1WhZnmYEz1UZd1uYncKiyhVbn0KePvXeikfykSDLjTMRFhGE26dl6qhGA9LO8CTDqtdx5fh57Sq3sLLFQZukgJlyP2RQ2zFd1dunmcKolOJpwntlXxUf+sI23C+tDvRQhxBhzur3sq2hmXUECEQYtV85P5Y71ufzz08v53U2LmJceE+olCiGEEEJMGRIciUGtyk0AICWmd3C0Jj8Bnwq7SoY2Xa2j08PuUgsXzkzqPpabENG95Swz9uyVQzctzyI52sB3njvC1lNNY1JtBP4tENXNju5+SmJi2HrKX+F230vHsLs8IV6NEGIsHahoweXxceuqHN7/1gX8/qZFKIpChEHHVQvS0GiUUC9RCCGEEGLKkOBIDGpVXjzQt+JoUVYs4XrtkPscbS9uwu1VOX9GYvex3ET/djWN0jeY6o9Rr+XBjy7AFKalwmpnZkr0UF/GsGTEhtPh8tLqkHBiovD5VHaetjAzJYrqFge/e6c41EsSQoyhnactaBRYnhuHoigoigRFQgghhBChogv1AsTEtjDTTHxEGNOTI3sdD9NpWJEbx7YhBkebTzQQadCxNDuu+1huoEF2SrQRvXZoGeb66Ymsn55IpdVOXETwt6nBmaar1S0OYkz6MbmHGBqXx4dOo3Civg1rh4t7Lp/F7tMW/rb1NNctTmd6clSolyiEGAM7S5qYlx5DtFH+HyyEEEIIEWpnfbeuKIpRUZQ9iqIcUhTlmKIoP/rQ479XFKW9x68NiqI8qShKsaIouxVFyenx2HcDx08oinJpMF+IGBthOg3vfet8PrNmWp/H1uQlUNLYQZ3NOeg1VFVlc1Eja/MTCNOd+ZLLDTTIzhjCNrUPy4wzEWEYm9wzvUdwJEJHVVUu++37fPPpQ+wIbIlclRfPdy+fRaRRx/efPyrbCYWYhBwuLwcrW1gZqHgVQgghhBChNZQyj07gQlVVFwALgY2KoqwEUBRlKWD+0Pm3A82qquYDvwZ+Hjh3NnAjMAfYCDysKIo2KK9CjKkoox5dPxVBa/L9/Y8eeusED715AmuHq9/nF9W1Udfq7NXfCCAvUHE00abjdFUcyWS1sfXotlLu31SIy+Pr9/FKq4OSxg6eO1DNI++XkBNvIt0cTlxEGN+9bCZ7yqw8s69qnFcthBhre8utuL0qq3IlOBJCCCGEmAjOGhypfl0VRfrADzUQ+vwC+L8PPeVq4F+Bnz8DbFD8zQmuBp5QVbVTVdVSoBhYHoTXIEJkZkoUaTFGntpbxe/eLeb5A9X9nvduUQMA63v0NwLIijdhCtOSlxTZ39NCJiEyjDCdZkQVRzaHm+8+d5i/bT2N0+0dg9X1z+dTufL3W7ntH3uobx28AmyieOFgNX/fVsqn/r6b5n5Cx92l/iqjtBgj9a2drMpL6H7shiWZLMmO5aevFfX7XCHEucHp9uJw9f5/5c4SCzqNwrKcuAGeJYQQQgghxtOQGssoiqJVFOUg0AC8parqbuBLwEuqqtZ+6PR0oBJAVVUPYAPiex4PqAocE+cojUbh5bvXsvO7F5IcbeBota3f89470cCctOg+DbYNOi1vfPU8bl/bdxtcKCmKQro5fNjBUWlTB9c+vJ0nPqjkJ68cZ8OvtvDsviq8vrHfTrW/opmj1a28d6KRS3/z/oB/FhNJU1snuYkRHKho4dqHt1PS2N7r8T2lVmJNev5+2zJiwvVsnJvS/ZhGo/DAtXOxOdw8+EbReC9dCDFKXp/Kf3eXs+Zn73LbP/b0emxHiYUFmeYx244shBBCCCGGZ0jBkaqqXlVVFwIZwHJFUc4DbgB+38/p/Y0+UQc53vvJivJ5RVH2Koqyt7GxcSjLEyEUH2kgNSaceekxHK5q6fO4ze5mX3kzF8xI6ufZ/l5FRv3E27GYbg4f9la1+146hqXdxROfW8n/PruC+MgwvvH0IS7/7VbeLaof0348mw7XEqbT8NKX1mDUafn6Uwfp9IxfxdNwqapKU7uLi2cn8/jnV9Dm9HDtH7f3mtK3p8zKspw4ZqVGc/Dei1k/vXfF2syUaG5fO43H91Syr9w63i9BCDEKT++t5HvPH8Xp9nKk2tb9/8f2Tg9Hqm2yTU0IIYQQYgIZ2iirAFVVW4D3gAuAfKBYUZQywKQoStd87CogE0BRFB0QA1h7Hg/IAGr6uccjqqouVVV1aWJi4ocfFhPU3PQYTjd10N7Ze4T9+6ca8alwwcz+g6OJKs1spLp5eMFRuaWD86YnsiI3ntX5Cbx41xr+ePNiOj1ePvPPvXzliYNjslafT+XVI7VcMCOR+Rlmfnr9PE7Wt/Pbt0+Nyf2CodXhweX1kRhpYEl2HC/ctYaUGCO3PrqH/+2uoM7mpNxiZ/k0/1aVgUZxf2VDAWkxRr73/FE83v57JQkhJp6jNTZiwvV8+7KZ2F1eGts6Afig1IrXp7JKGmMLIYQQQkwYQ5mqlqgoijnw83DgImCfqqopqqrmqKqaA9gDzbABXgJuDfz8o8C7qv+jxJeAGwNT16YBBUDv+nRxzpqXHoOqQmFNa6/jm4saMJv0LMz8cA/1iS3NHE5DW+eQq3ZUVaXW5iQ15sx2PEVRuGJ+Km99fT1fOC+Xlw7VsKNHRU2w7C1vpqGtkyvmpwFwwYwkbliSwZ+3lJx14l2oNLb73yQmRhkAf+XZs3euZm1BAvc8f4Qv/ncfACumDf7mMcKg476r5lBU18Y/d5SN6ZqFEMFTbrGTHW8iJ94/JKG0qQOAnacthGk1LMmODeXyhBBCCCFED0OpOEoFNiuKchj4AH+Po02DnP93ID5QgfR14DsAqqoeA54CCoHXgbtUVZ24e2nEsMxLjwHgSI/eOj6fynsnG1k/PRGtpv+KkYkqPTBZbajBS7Pdjcvj6xUcddFrNXzt4umkxhj5xZsngr5l7ZXDNRh0Gjb0qOq6bU0OPhV2lAQ/qAqGpkBwlBBp6D4WZdTzt1uWctvqHPZXtBBp0DErNeqs17pkdjIbZibx0FsnZRKeEOeICqudrLgzwVGZJRAclVhYmGWekFuYhRBCCCGmqqFMVTusquoiVVXnq6o6V1XVH/dzTmSPnztVVb1BVdV8VVWXq6p6usdjD6iqmqeq6gxVVV8L3ssQoZYUbezTIPtwtQ1rh2vA/kYTWVdwNNQG2bU2/3n9BUcARr2Wuy8s4EBFS/eUuWDw+lRePVrHhTOTejWSnZUSjdmkZ2eJJWj3Cqb+giMAnVbDD6+aw68/voD7PjIbnfbs2baiKPzwqjn4VJUfv1w4JusVQgSPx+ujutlBdryJNLMRvVahtMmOze7maI2N1bJNTQghhBBiQhlWjyMhBvPhBtmbixpQFDhv+rnXqyo91h8cVQ3S58hmd/O954/Q3unprkxKiQkf8PwblmYQHxHGK0c+PIhw5D4os9LY1skV81N7HddoFFZOi2dHiWVMm3KPVFNbV3AU1u/j1y7K4Ialmf0+1p/MOBNf3lDA68fqeLeoPihrFEKMjZoWJx6fSlacCZ1WQ2acibKmDnaXWlBVpDG2EEIIIcQEI8GRCJquBtltTjcAbx+vZ2GmmbiI/sOBiSzdHE6YVtNnRHxPO0qa+O/uCrYXN1EbCI4GqjgC/5a17HgTtS3B6zv0yuFajHoNF/bTfHx1fjzVLQ4qrYNXTT22q5znD1QFbU1D0djeiVajEGsK3tfGZ9fmUpAUyb0vHsPhkl2wQkxU5Vb/trSsOP82tWnxEZRZOth52oJBp2Fh1rnVE08IIYQQYrKT4EgEzZr8BFTVPxr+aLWNYzWtXLUgLdTLGhGdVkNuYgTF9QMHRw2BqpnihnbqbE60GqXP1qsPSzWHd29rGy2vT+W1o7VsmJmMKUzX5/Gu7R47Tw/c50hVVX7z1kn+ub0sKGsaqqY2F/ERYWiC2PsqTKfh/mvmUtXs4A+bJ+5EOSGmunKLHYDseFPgvxGUW+zsLLGwNCcWg076GwkhhBBCTCQSHImgWZody8yUKP61o4z/7anAoNNw3aKMUC9rxPKTIjnVMHBw1DU++mR9G7U2J8lRhrM2AU+LMVJrcwZl+9juUgtN7a4+29S65CVGkhhlYMcgfY6qmh1YOlyUW+2jXs9wNLV3njVkG4mVufFcvziDR94/TXFDW9CvL4QYvQqrnTCdhpRof4XmtAQTDreXoro2VuclhHh1QgghhBDiwyQ4EkGjKAq3rc6hqK6Npz6o5Ir5qcSY9KFe1ojlJ0VS2WwfcNtTQ5t/y9nJ+nZqbQ5SBtmm1iU1JpxOj49mu3vU63vlcC3heu2AzccVRWFNXjybixqwOfq/34FKf0+qFrsbWxDWNFRN7Z0kRAU/OAK45/KZmMJ0fP+FoxOyv5MQU125pYPM2PDuisOchIjux1ZKfyMhhBBCiAlHgiMRVFcvTMds0uPxqXxiRVaolzMqBUlRqCoD9jnqqjgqaWynusVB6iCNsbukmf3h0mjHxnu8Pl4/WseGWUmEhw28reOz63Jp6/Twp/dK+n38YMWZZuZdfUfGQ1O7a8DG2KMVH2ng2xtnsuu0lecPVI/JPYQQI1dhdZAdfyYsygn83BSmZX5GTKiWJYQQQgghBiDBkQiq8DAtX7ogn4tmJbE4KzbUyxmVguRIYJDgKDBS3uXxUW6xD6niqGvqWlcz7ZHaXWrF0uHiygG2qXWZmx7DtQvTeXR7KdX9hFUHKpu7m5d39R0Za6qq0tjWSeIYbFXrcuOyTBZlmXnglePjWkklhBicqqpUWDrIijN1H0sLDCNYlhOHXivflgghhBBCTDTyHZoIus+uy+Vvty5DUYLX+DgUcuIj0GoUTg3QILuhtZOZKVHdvx5solqXtMA5o22QvelwLaYwLecPsE2tp69fMh2AWx/dw/MHqnB7fYA/8DpW08rl81IA//aR8dDq9ODy+kgco61qABqNwgPXzKPF4ebnbxSN2X2EEMNj6XDR4fJ2N8YG0GoUvn/lLO6+MD+EKxNCCCGEEAOR4EiIAYTpNOTEmzjVT5Nlr0/F0uHq1Y9jKBVHCZEG9FplyBVHlVY7rx+t7XXM4/XxxrE6NsxKxqg/+/ShjFgTf/rEYjQKfO3JQ5z/i/f4x/ZS9lc04/L4WJ2XQFKUYdwqjpoClVpj0Ry7p9lp0dy2OofH91RwoKJ5TO8lhBiawppWoHdfI4BbVuWwNCcuFEsSQgghhBBnIcGREIMYaLJas92F16cyLSGCdLN/+9lQKo40GoXkaCO1Q+xx9Netp7njP/s5Xut/s3W02saNj+zC2uHiqgVpQ34dG2Yl8/pXzuPvty4lzWzkRy8XcvNfdwGwMNNMdrxp/IKjtvEJjgC+dvF0kqOMfO/5o3gClVZCiNB5bn8V0UYdq6QJthBCCCHEOUOCIyEGUZAURbnFTqen92S1hlZ/+JEYZWB6oBdSyhCaYwOkxYRTM8SKo67+Sn/YXMzRahvX/WkHZZYOHrx+PhfNOvs2tZ40GoUNs5J5+o7VPHvnKjbMSub8GYmkxhjJjo8Yt+bYTe0uABKixqY5dk+RBh33fWQ2hbWt/Htn+ZjfTwgxMJvDzWtH67hqYdqQqiWFEEIIIcTEoAv1AoSYyGanReP1qbxVWM+V889U+HQ1xk6KMjAnLYYdJRaShtizJyXGyIHKoW2dOt3YgU6j8OqRWg6UNxNnCmPTl9eOulpnSXYcf73lzLaQ7DgTz7R24nB5B53SNhqNbZ3c++JRbA5/s+rxqDgC2Dg3hfNnJPKrN09w+bzUIW0pFEIE36bDNXR6fHxsaWaolyKEEEIIIYZBKo6EGMQls5OZmx7ND18qpMXu6j7e2Ham4ugL63N59s7VQ54GlGo2Umdz4vOpg57X0emh1ubkllU5GHVa6ts6+cPNi8YkcMkKNKqtsI7ddrW3Cut57WgdO09biDbqiDWNfcURgKIo/PiquXh8KvdvKhyXewoherO7PPxvdwUzU6KYlx4T6uUIIYQQQohhkOBIiEHotBoevH4BLXYX92863n28oc2/1SwxykCUUc/cYbwRSosJx+31N9ceTGmTf+vY0pxYfv3xhfzx5sVj1jw2J97fqHYsJ6sdqmzBbNJz8N5LePsb69Fqxm/qXla8ibsvzOeVI7W8d6Jh3O4rhIAdxU1s/M1WjtW08rl1uef8xE0hhBBCiKlGgiMhzmJ2WjR3rM/j2f1VbDnZCPgrjiINOkxhw9/t2dVEu9Y2eIPsrv5GuYkRbJybwsa5KcO+11B1jcbuCqvGwqGqFhZkmIkJ15MUNf7bxT53Xi65iRHc++IxnG7v2Z8wxbk8vu6vQSFGwuZw851nD3Pz33aj1Sg8+fmVXL8kI9TLEkIIIYQQwyTBkRBD8KUL88lLjOCe547Q3umhsa2TxCH2NPqwtMAUtkrr4MHR6cYOFOVMNdBYMpvCyI43sbd8bMbWd3R6OFnfxoJM85hcfygMOi0/uWYuFVY79zx3hH3lVrxn2S44ETS1d7J5nKukVFXl608d5LLfbKWj0zOu9xaTw5vH6rj4oS08tbeSL6zP5bWvrGOFTFITQgghhDgnSXAkxBAY9Voe/Oh8amwOfvnGCRraOkkcYa+h/KRIEqMMPPJ+yaB9jk43dZBuDh+36UOr8+LZddoyJmHK0WobPhUWZoa2t8nqvARuW53Dcwequf5PO/non3ectfIr1P69o4xP/+MD/vDuqXG75+N7Ktl0uBaX10dV88T+/RETS1N7J1/6334+/9g+4iLCeOGuNXz3slkyRU0IIYQQ4hwmwZEQQ7QkO45bV+Xwr51lHKu2kRg9suDIqNdyz+UzOVRl46m9lQOed7qxnbzEyBGudvhW5SXQ5vRwrMYW9GsfqmoBYH5G6CqOuvzwqjns+/5F/Oy6eZysa+PK322jcgybgo9W1wS/X755kj9uLh7z+xXVtfKjl4+REeuvjKtpkeBInJ2qqjx/oIqLHtrCm8fq+cbF03n57rUT4u+8EEIIIYQYHQmOhBiGb106g7SYcDpc3hFXHAFcszCdZTmx/Pz1on63Avl8KqcbO8hNHPttal1WBbaR7Cix8OQHFVz5+63YHO6gXPtQpY2M2PAxmQg3EvGRBm5cnsVjn12BpcPFrtOWUC9pQJZ2F/lJkVy7KJ1fvHFiTMMju8vDl/53gCijnj9/cgkAVRIcibOoaXHwmX9+wNeePMS0hAhe+fJa7t5QMORJk0IIIYQQYmKT7+qEGIYIg46fXjcPgPRAr6KRUBSFL56fT7PdzeGqvhU+da1OHG4vueNYcZQYZWB6ciQvH6rhRy8XcrS6NWjbow5VtYS0v9FAchP8wVybM7h9fF49UsvpIDWWbra7SIw08MsbFnDNwjR+8cYJHn5vbMKjH750jJLGdn5740Jmp0aj1yrjUnGkqhO/15Toy+dTeWxXOZf8+n12nbZy75WzeeaO1RQkR4V6aUIIIYQQIogkOBJimM6bnsgzd6zixuWZo7rOvAx/v5/+tobtr/A3qc5LGL+KI/D3ADpW04pPVdkwM4l/7igb9aQ1m91NVbOD+emh7W/UnwiDfypeexAbQDtcXu5+/ACPbi8NyvUsHS7iIsLQahR+9bGFXL0wjQdfP8Gf3isJyvW7vHiwmqf2VnHX+fmsyU9Ao1FIjQmneox7HG091cjKn77DL984Mab3EcF1urGdGx/ZxQ9eOMrCTDNvfu08PrN2GlqNEuqlCSGEEEKIIJPgSIgRWJoTR5RRP6prJEQaSIk2cqymtdfxpvZOfvhSIdOTI1mcHTuqewzX6jz/drWvbJjOz66fj0Gn5YFXCkd1zTKLP3gaz+qpodJrNYTrtbQ5g7MlD6CwthWvT6XO5gzK9ZoDwRHgD49uWMBVC9L4+etFvFtUH5R7lDZ1cM9zR1iWE8tXLyroPp5mNo5pxdFjO8u45dE9tNjd/HlLCcUNwanSEmPH4/Xx5y0lXPbbrRyva+XB6+fz2O3LyYwzhXppQgghhBBijEhwJEQIzUmL7lVx5POpfPPpQ7Q63fzupkXjPonoolnJPHrbUj63bhqJUQbuuiCft483sPVU44iv2RUc5cRPzDeWUUZdULeqHQk0Aq9v7Rz1tbw+lRaHuzs4AtBpNfzqYwvIiA3n4c2jrzry+VS+/tRB9DoNv71xEboefWnSzSaqxyg48vlU/rC5mGU5cbz99fWE67X8ZJQhpRhbhTWtXPPwdn72WhHrpyfy9tfX87FlmSiKVBkJIYQQQkxmEhwJEUJz0mMobmjH4fIC8I8dZbx3opEfXDGLmSnR474ejUbhwpnJ3eHBZ9bmkBVn4v5NhXi8vhFds9xiR1GYsBUJQQ+Oqv0VZHWto684arG7UFV6BUfgr5T63Lpc9pY3s7fMOqp7PLOvigMVLdx75WzSPtS3K91spL7ViXuEf/aDOVJto761k48vzSQzzsRXLirgvRONfDDK1yOCr9Pj5VdvnuCqP2yjzubkjzcv5i+fWkJytDHUSxNCCCGEEONAgiMhQmhOWjQ+1T8C/Wi1jZ+9dpyLZyfzyZXZoV4aAAadlnsun8XJ+nYe31Mx6LleX/8NjsssHaRGG8e9emqoIo162oLY4+hItb/iqKm9c9SBi7XDBfQNjgBuWJpBrEnPn7ecHvH1bXY3P3+9iGU5sVy7KL3P4+mx4fhUgrbtrqe3CuvRahQunJkEwNUL/fc/Wt2355cIrfs3FfL7d4u5amEab31tPVfMT5UqIyGEEEKIKUSCIyFCaE6av6rogzIrX378APERBh68fv6EelN26ZxkVuXG89BbJ7HZ+/YCcrq9PPTWSebc9zr/3lnW5/Gypg6y48e3yfdwRBt1QetxZHd5KG5oJznagKpCY9votqtZBgmOTGE6blmVw9vH6ykZxgS3Nqe7e4rZP3aU0mx38cOr5vT7NddVgTQW29XeKqxnaXYssYHXlhAZRrheS6V17Ke4ieHZUWLhollJPPSxhd1/XkIIIYQQYuqQ4EiIEEo3h2M26fnlmycptXTw0McXTLg3Zoqi8IMrZ2NzuPnNOyf7PH7Lo3v43TuniDOFcf+mQo5U9a4YKbfYyUmYmNvUILhb1QprWvGpsGFWMjD67WrNgwRHAJ9cmY1eq/DYzvIhX2/l/3uHJz6oBGB7cRPzM8zMSet/4l16IDgKdoPsCoudE/VtXDInpfuYoihkxoVT2WwP6r3E6LR3eiht6mB+hjnUSxFCCCGEECEiwZEQIaQoCnPSonF5fNx1fj6r8xJCvaR+zU6L5uPLsnhsZzmbTzR0H6+zOdlTauWrFxXwypfXER9h4O7H93ePt291urF0uCZ0xVGUQR+0iqPDgdDs4tn+4Kh+lFu8Bqs4AkiMMnDl/DSe3ls5pNewtbiJDpeX147W4XR7OVRpY8W0uAHP7644anZ0VykFw5uFdQBcEvh96pIZa6LSKsHRRHKs2oaqwrz0/sNFIYQQQggx+UlwJESIXbcogyvnp/KVHmPQJ6JvXjKdnIQIPv2PD/i/Zw7h86nsKGkC/EFJbEQYv71xIRVWOz944SjgryyBiTtRDSDSqKM9SBVHR6ptJEUZmB94k10fpIqjWNPAVWi3rc6hw+Xl2X1VZ73elhP+6Xi7T1vYddqCy+tj+SDBkVGvJSEyjB0lFtb/4j1++NKxYb6C/r1VWM/MlKg+DdMz40xUBTmkEqNzJNBzaq4ER0IIIYQQU5YER0KE2PVLMvjDzYvRayf2X8f4SAOb7l7L7Wun8dTeKracamRbcRNxEWHMCkyAW5Ebz1c2TOf5A9U8u6+KMksHADkJE7jiyKijw+UdsLn3cBypj3LRWwAAIABJREFUtjE/I4ZYUxh6rUJd6+h7HEUZdITpBv7aWJBpZlGWmT9sLqG0qWPA83w+lS0nG0mJNtLp8fH7d/9/e/cdH1d15338c0ZdVpdGxZKwLVuy3G1wAQM2mGZ6CwtssiGELAmbTdsnu8kuu2kbSEhjE/bJPuEFBEIIpIATloRiIMY027jgbsm2XCTZlmWrS1ad8/wxV2Jsj8pIY82M9X2/Xvfl0Zk79547P48085tzfmcPxsD8Cf0njsA76uj9iuMcaWrnyff2s2LT4AmqgdS1dvLB/rq+UVm+CtITaOnopsFPLa3+WGv53l92svNw04j6Jf5tq24kJyUOd3JcqLsiIiIiIiEy6CdVY0y8MWadMWazMWa7MebbTvszxpgyY8w2Y8wTxpgYp90YY35mjNljjNlijDnX51h3GWN2O9tdZ+6yRORMiI+J4mvLS8lKiuOZNQd4b89xLijKxOX6qLDyPy6bwqJJGfzHn7bx5i7vtLZzMsJ3xFFyfAzAiEcdtXR0s7e2hZn5qbhchuzk+JGPOGrrJCNp8JpXD906G4+13PHo+xw47j95tONwE8daOvjCZVOIi3ax4UA9pbkppCbGDHjsc89JpzQ3mde/spSFkzL4txe29Y0kG443dx3FY/GbOOodgRRInaODdW38YnXFkEZcSeC2VjdqmpqIiIjIGDeUIQ4dwDJr7RxgLrDcGHM+8AxQCswCEoDPOPtfDRQ7273A/wAYYzKAbwKLgIXAN40x6cG7FBEZDbHRLu5YUMjrO49ypKmdC6ecXJcpymX46R3ziIt28cLGanJS4kiMjQ5RbweXHO/tW9MI6xztONSEtTC7wPshOzc1fsTL2Ne1dvZb38hXSU4yv/n7RbR19PDT13f73eetcu80tSum57CoKBNgwPpGvb55/XRe/tLFnJOZyEO3zuZEVw+rd9cGcBUnW7njCLkp8X6TEYXpTuIogJXVdhzyjjQqq2kedp/Ev5aObiqOtWqamoiIiMgYN2jiyHr1rvUc42zWWvsX5z4LrAMKnH1uBH7l3LUGSDPG5AFXASuttXXW2npgJbA82BckImfeHQsL6V29/cIpmafdn5saz49umwMQ1oWxAVKcxFFvQe/h2lLVAHxUCyY3ZeQjjupaO8kYoL6Rr9LcFBYVZbLZ6Ycvj8fyyrYjzBifQnZyPEtL3AAD1jfqZYzBOMGekJFIbLRr2CuftXf1sLr8GJdPz+47pq/CDG8x7oMBFMjunaK2u6ZlkD0lUDsPN6kwtoiIiIgMrcaRMSbKGPMhcBRv8metz30xwN8BrzhN+UClz8OrnLb+2kUkwhSkJ3Ll9ByK3OP6nYZ22bQcHrh5Jp9dUjTKvQtMUpx3qlbzCKeqba1uJDclnuzkeABygpU4GsKIo16z8lOpONZ6WhLsF6sr2FrdyF2LJwJw67n53LukiEunZgfUH5fLUJCWQFUAI4J8vbvnGCe6erhieq7f+5PjY0hLjAkoMbXjsHek0ZGmdhpPBGd1PPH68KA3CanEkYiIiMjYNqTEkbW2x1o7F++oooXGmJk+d/8cWG2tfdv5+fSvkcEO0H4SY8y9xpj1xpj1tbXDnw4hImfWw7fP5Q+fW+x35Eivjy+awGXTTq9lE056p6oNZTn7gWytbmRWwUcfsHNT42jt7KG5vYuO7h5+srKcH79WNuTjWWs5HmjiqCAFa71LqPf6sLKBH79WxrWz8rjtPO/A0LTEWP7tmmkkxEYN+di98tMThj3iaOWOGpLiojm/qP+RToXpiVQGOOIozanTtFvT1Uaks9vD917eycaD9QC8vecYk93jyE6JD3HPRERERCSUAlrGyVrbAKzCmWJmjPkm4Ab+yWe3KqDQ5+cC4NAA7aee41Fr7Xxr7Xy32x1I90RkFCXGRgeU1AhXHyWOhj/iqLm9i4raVmb7jMzIcT5sv7j5ENf97B1+9sZuHnlzz5CTG22dPXR2ewJ6jnunyfUuod7c3sWXnttETko8D94ya8Ak31AVZgSW2OnV47G8vrOGpVPdxEX3n7AqzEigqn5oI5oa27qobjjBtbPyACjXdLU+ga4SaK3la89v4RdvVfCDV3bR3tXD2orjLCnR32ERERGRsW4oq6q5jTFpzu0E4HJglzHmM3jrFt1prfX4PORF4JPO6mrnA43W2sPAq8CVxph0pyj2lU6biEjI9K6qNpIRR9uqvXV2Zhacnji6f8U2Wju6+a/b5xIX7eKJd/cN6Zh1rZ0ApAeQOMpOjic3Jb4vcfSNP22nsq6Nn94xl9SEgVdPG6rC9ETq27oCrgn1YWU9x1o6udLPamqnHr+6/gSvbj8yaIJqh1Pf6PLpOSTGRlGuEUd9o9um/ccrrNxRc9r9nd0e7nx0DZf+aBVXPbya6x55m1t+/i7X//c7rNhUTXF2Emsq6njxw0N0dHtYUqzEkYiIiMhYN5SljvKAp4wxUXgTTb+z1r5kjOkGDgDvO99iv2Ct/Q7wF+AaYA/QBtwNYK2tM8b8J/CBc9zvWGvrgno1IiIB6htxNILi2NucRI1vLZgZ41O4ZKqbi6Zk8YnzJxAfE8Xafcd5YWM1/3xV6aAjiXoTR5kBjuqamZ/K1upGVmyqYsWmar5yeQnzJw5eBHuoegtYV9W3UZqb0u9+q8qOsqqslm/dMAOA13bUEO0yXDJIXaWpucl09nj47NMbSIqL5qUvXMTELP8F1nsLY88Yn0JxdhK7j47txNH6/XV87fkt7K1txWXgr2VHueKURN3q8lrerzjO0hI3CTFRdPV46OzxEN3t4Z+uKOHGueNZ+sNVPPjyTmKjXCwaYFqhiIiIiIwNgyaOrLVbgHl+2v0+1lll7fP93PcE8ESAfRQROWPiol3ERBma27tp7+qhvauHtCGuZNZrS3Uj41PjyUqK62tLjo/hybsXnrTf3RdO4tl1lTy77iCfv3TKgMfc7iwzPz4tIaC+zC5I5fWdNfz7im0snJjBPy4b+DyBKkz3FkOvrDsxYOLombUHWbmjhs9fOgV3chwrd9RwflHmoCOfbp6Xz+yCVI63dHLv0xv4wrOb+MN9F/id3rbzcBNZSXFkJ8dTkpPMX8vGZl285vYufvBKGU+vOUB+WgJP3r2Ax9/Z11fc2tefNh8iPTGGx+6aT0yU/0HH885JY9PBBhZPziQxdijfL4mIiIjI2SygGkciImcbYwzJ8TE0t3fx3T/v4IqHV9PYFti0ta1VDScVxu5PSU4y8yek88q2I4Pu+9v1lZTkJFGamxxQX3pHPUW5DA/fMZco18jrGvkqSPcmsgaaRmat5cNKb9Ji08F6KuvaqKhtZVnp4Ku4GWOYkp3MoqJMfvix2WytbuT7L+86bb+jze2sKq9lZr43eVWSk8yxlg4qalvwfn8xNlTUtnDFT1bz67UH+PSFk3jtK0u4ZGo2cwvTKKtppq3zo5F0LR3drNxxhGtn5/WbNAK4aa53wdOLNU1NRERERBjaVDURkbNacnw0ze3dlB1ppra5g4de3cWDN88a0mMbT3Sx/3gbt80vHHxn4JKpbn70WjnHWjpOGqHka+fhJjZXNvCN66YHXND63AnplOQk8c9XlZIf4GilocgYF0tibNSAK6tVN5ygtrkDgI0HG2hwEnEXFWcFdK4rZ+Ry94UT+eW7+zm/KJOrZuQC0N7Vw72/2kBLezdfvXIqADOcBNKyH79FWmIMJTnJlOYmU5KTzLWz8gKqFRVJXtpymJrmdl64bzHzzknva59bmEaPx7K1qpFFRZkAvLb9CO1dnr7EUH9umpfP5soGbp438H4iIiIiMjZoxJGIjHlJcdEca+lg99EWUuKj+c3ag31Lkg9mu1PfaGb+4COOAJaWeEfdvL27/2lVv/2gktgo17A+uKcmxPDaV5aeVtsmWIwxFKYnUlnX/8pnm5wpUsnx0Ww6WM+7e4+RlRRHcXZSwOf7+tWlzMxP4Z9/v5kqJ1n13T/v4MPKBh6+fW7f835BUSa//9wFfOv66Vw9M48ej2XFxmr+/Y/b+PHKsmFcaWTYc7SF/LSEk5JG4E0cAX0jvwBe2FhNQXoC5004ed9TpSbE8JPb55KbGh/8DouIiIhIxFHiSETGPG+Co4Eej+Ub188gNyWe+1dso7vHM+hjt/opjD2QGeNTyEqKZVU/9Xi6ejys2FTN8pm5YTtKpjAjoS+J48+mgw3ERbu4ce54tlQ18u6e4yyenBnw6CmAuOgo/vvOc/FY+OKzm9hwoI5n1h7k7gsnsnxmbt9+xhgWTMzgUxdO4nu3zOL5+xaz5VtXsqw0m7fKa8/a6Wt7jrYwxU9CLjMpjsKMhL7E0YYD9byz5xh3LjxnWHEQERERkbFLiSMRGfOS42No6+wBYNGkDL51w3R2Hm7iyff2D/rYLdWN5KclDLpKWi+Xy7Ck2M3q8lp6PKcnM8qONNN4oovLz9CIoWAoSE+kqv5Ev8mYTZX1zC5IZcHEDE509XCspYPFkzOHfb6JWeN48JZZbDzYwCceW4c7KY5/uqJk0McZY7hkqpvKuhPsP95/oitS9Xgse2tbmOL2P5JrbmF6X+Lo4ZXlZI6L5VOLJ45iD0VERETkbKAaRyIy5iXHe38VpibEUJCeQEF6AstKs3l4ZTnXzs4jL7X/WkFbqxqZPYTC2L6WTnXzwqZqtlU3MseZUtSr94P+3II0fw8NC4UZibR0dHP1T98mKymOjHGxZIyLxZ0cx9ISN9sPNfGpxRM512f61IVTAqtvdKob5ozn/b3HeXbdQb5/6yyS4wdena3X0hJvgefV5bVMyho3oj6Em+r6E3R0e/yOOALvdLX/3XyIzz69nnf2HOP+a6YxLk5/9kVEREQkMBpxJCJjXoqThJiZn4IxBmMM375hBj3W8p3/3dHv4xrbujhY1zakFdV8XTQlC2PgrfLTp6ttqWogPTGGwozgF7YOlmtn5XHnwnMoSE+gtbObzVUNPL+hih++WsZ1j7xDZ7eHeYVpFKQnkOVMmSrMSBzxeb9z4wxW/MNibpgzfsiPmZA5jgmZiaz281xHuj21zQD9Jo6un53HNbNyWbevjoL0BD5x/oTR7J6IiIiInCX01aOIjHlJzigM3wLXhRmJfGFZMT98tYw3d9WwrPT0qWM7jzQBMGN8YImjzKQ4Zuen8lZ5LV+8rPik+7ZUNTK7IC2s69DkpsbzvVtOX3WurrWTZ9cdZMOBehZPycIYw1euKCYhJioo542Jcp1WBHoolhS7eX5jFZ3dHmKjI//7Emstxhj2HG0B+k8cZafE8/OPn4fHY/FYS3RU5F+7iIiIiIw+JY5EZMzrnao285QE0N9fXMSKTdV840/bWTw5i/hTEiA1Te0Aw1r2funUbP77zd00tnWRmugd8dTW2U15TTNXzsgd5NHhKWNcLJ+/dMpJbR9fFPpRLktK3Dy95gAbDtRzwQhqLYXaz97YzRPv7qPpRBdfvKyYQw0nyEqKJS1x4PpaLpfBRfgmIkVEREQkvOnrRxEZ87KS4gBOq1UUG+3iG9dNp6r+BK9uP3La43oTRzkpcQGfc2mJG4+Ft/d8NIVqW3UTHgtzApz6JgNbVJSBy8CaiuOh7sqI/GXrYdITYzlvQjr/s2ovH+yvZ3I/hbFFRERERIJFiSMRGfOum5PH8/ctZkLm6cWTL5qSxfjUeP64qRprLZ99ej3/+ZK37lFNUweJsVF9U90CMacgldSEGN4q+yhxtNkpjD07jAtjR6KU+Bimj09h3b66UHdl2Dwey/7jrSwrzebHt82lx2PZd6y132lqIiIiIiLBosSRiIx5cdFRnDfBf+0cl8tww9x8Vu8+xh8/rObV7TW8t9c7cuVocwfZyXHDqkcUHeXiouIs3iqv7VvWfnNVA/lpCbiTAx/BJANbODGTjQfr6ejuCXVXhuVwUzvtXR6K3OM4JzOROxeeA/Rf30hEREREJFiUOBIRGcRN88bT47F87Q9bAaiqbwO8U9WyU+KHfdylJW6ONnew60gz1lo2HKhnbqFGG50Ji4oy6Oj2sLWqMdRdGZaKWm8h7KIsb6Loi5cVs7TEzSVTs0PZLREREREZA5Q4EhEZRGluCqW5yXT2eJgxPoXm9m4aT3RxtKmdnBEkji4pcQPwVnkte2tbONzYzkXFWcHqtvhYMDEDgLUROl2torYVgMlu73RKd3IcT316IZOyTp9eKSIiIiISTEociYgMwT9cOoWrZ+byuaWTAe+oo96pasOVnRLPtLwU3iqrZXX5McBbU0mCL2NcLCU5SWGfONp5uImyI82nte871sq42ChNYxQRERGRURd4RVcRkTHohjnjuWHO+L4C1mVHmmnr7BnWimq+lpa4efydCno8lklZ4yjMSAxGd8WPRZMyeWFjFV09HmKiwu97k64eD598Yh1NJ7p4/K4FJ40+21vbQpE7aVj1tERERERERiL83jmLiISxgvQEADYerAcY0VQ18CaOunos6/bXcbGmqZ1Rl0x109rZwyqflezCyWvba6ht7iA5PoZ7nvqA1eUf9bOitpUit6aliYiIiMjoU+JIRCQAGeNiiY9xsfGAd+RRdvLIEkfnTUhnXGwUABcXu0fcP+nf0hI37uQ4fre+MtRd6WOtZXeNtzj6r9ccID8tgVe+fDFF7iQ+86v1rCo7SntXD4caT6iekYiIiIiEhBJHIiIBMMZQkJ7IriNNAGSPcKpabLSLC6dkEeUynF+UEYwuSj+io1zccm4+b+46ytHm9lB3B4CXtx3hiodXc9v/e5/3K47zt4vOISspjt98ZhHF2Unc+6sNPPnefqyFIndSqLsrIiIiImOQEkciIgHKT0vAY723RzpVDeBflk/lkTvnkRwfM+JjycBuO6+QHo9lxcbqUHcFgFe2HSEpLppdR5qJjXJx+4JCANLHxfLMZxYxNTeZ77+8C4AijTgSERERkRBQ4khEJEC9dY7GxUaRFDfyNQamZCdzzay8ER9HBjclO4nzJqSzYlPoE0fdPR5WlR1l+cxc3vw/S/nj5y8kK+mjEWxpibH8+p5FzC5IJSbKaKqaiIiIiISEVlUTEQlQQbp35bNgjDaS0besNJsfvlpGfWsn6eNiQ9aPjQcbaGrvZllpNtkp8WT7+f+UmhjDc/eez/5jbYwLQpJSRERERCRQGnEkIhKgfGfEkTt5ZPWNJDQWTPTWklp/oH7Uz93jsTyz9gBv7qrhjV01RLvMoKvpJcZGM318yij1UERERETkZPr6UkQkQL1T1TTiKDLNLkglNsrFB/vruGJ6zqidd9+xVr76+81scBJWCTFRLJyUodpWIiIiIhLWlDgSEQlQQVpv4kgjjiJRfEwUcwpTWbevblTO5/FYnnp/Pw+9sovYKBc/um0O5TXNPLq6gqtV20pEREREwpwSRyIiAcpKiuPaWXlcOjU71F2RYVowMYNHV1fQ1tlNYqz3T2FXj4e1FXVEuQwXTM4Mynkq69r46u83s3ZfHZdMdfP9W2aTm+odqXbPRZPI1nRHEREREQlzShyJiATI5TL834+fG+puyAgsmJTBz1ftZU3FcTweeHnbEV7fWUPjiS5io1y8+/VlI65hVd/ayTU/extr4aFbZ/E38wsxxvTdr6mOIiIiIhIJlDgSEZEx57wJ6bgMfPrJ9QAkx0dzxbQczpuYzv0rtvGbtQf50uXFIzrHziNNNLd388tPLeDSUo1OExEREZHIpMSRiIiMOSnxMXxu6WTq2zpZPjOPC4oyiY32LjS6ckcNv157gPsumdzXNhxVdScAmOxOCkqfRURERERCQYkjEREZk/5leanf9rsvnMRdT6zjz1sPcfO8gmEfv7K+DZeBvDRNSRMRERGRyDXoV6nGmHhjzDpjzGZjzHZjzLed9knGmLXGmN3GmN8aY2Kd9jjn5z3O/RN9jvWvTnuZMeaqM3VRIiIiw7WkOIvi7CQeeWMPHd09fe3WWrp7PEM+TlX9CfJSE4iJGv6oJRERERGRUBvKu9kOYJm1dg4wF1hujDkfeAh42FpbDNQD9zj73wPUW2unAA87+2GMmQ7cAcwAlgM/N8ZEBfNiRERERsoYw/3XTqPiWCuPv7Ovr/3nq/ay8ME3+GB/3ZCOU1nXRkF6wpnqpoiIiIjIqBg0cWS9WpwfY5zNAsuAPzjtTwE3ObdvdH7Guf8y411G5kbgOWtth7V2H7AHWBiUqxAREQmiS6Zmc8X0HB55Yw+HGk7Q2tHNL97aS11rJ594bC0rd9QMeozK+jYKMxJHobciIiIiImfOkMbPG2OijDEfAkeBlcBeoMFa2+3sUgXkO7fzgUoA5/5GINO33c9jREREwso3rpsOwJef+5Bn1x2kqb2bx++aT2leCp99ej3PrTvY72M7unuoaeqgMF2JIxERERGJbENKHFlre6y1c4ECvKOEpvnbzfnX9HNff+0nMcbca4xZb4xZX1tbO5TuiYiIBF1hRiLfv3UW6/bX8eBfdnLehHQum5bDs3+/iIuL3Xz9ha088sZurD3tTxnV9d4V1TRVTUREREQiXUAVO621DcAq4HwgzRjTuypbAXDIuV0FFAI496cCdb7tfh7je45HrbXzrbXz3W53IN0TEREJqhvn5vPpCyfhsXDvkiIAEmOjeeyu+dwyL58fryznmy9up8dzcvKo0kkcaaqaiIiIiES6oayq5jbGpDm3E4DLgZ3AX4GPObvdBfzJuf2i8zPO/W9a79exLwJ3OKuuTQKKgXXBuhAREZEz4f5rp/HnL17EVTNy+9piolz86LY5fHZJEb96/wBfeHbjSSuwVda1AVCYoRFHIiIiIhLZogffhTzgKWcFNBfwO2vtS8aYHcBzxpjvApuAx539HweeNsbswTvS6A4Aa+12Y8zvgB1AN/B5a20PIiIiYSzKZZgxPvW0dpfL8K/XTMOdHMd3/7yT+tYP+MUnzyMlPoaq+hPERBlykuND0GMRERERkeAZNHFkrd0CzPPTXoGfVdGste3Abf0c6wHggcC7KSIiEp4+c3ERWUlxfPX3m7n9F2t46u4FVNa3kZ+WgMvlr7yfiIiIiEjkGMqIIxERERnATfPyyRgXy+d+vYHlP30bl4FpeSmh7paIiIiIyIgFVBxbRERE/FtS4ub5+xYzY3wKx1o6mexOCnWXRERERERGTCOOREREgmRaXgpP37OIXUeayEtVYWwRERERiXxKHImIiARZaa6mqYmIiIjI2UFT1URERERERERExC8ljkRERERERERExC8ljkRERERERERExC8ljkRERERERERExC8ljkRERERERERExC8ljkRERERERERExC8ljkRERERERERExC8ljkRERERERERExC8ljkRERERERERExC9jrQ11H/pljKkFDoS6H9KvLOBYqDshAVPcIodiFVkUr/CnGEUOxSqyKF6RSXGLLIpX5IiUWE2w1rqHsmNYJ44kvBlj1ltr54e6HxIYxS1yKFaRRfEKf4pR5FCsIoviFZkUt8iieEWOszFWmqomIiIiIiIiIiJ+KXEkIiIiIiIiIiJ+KXEkI/FoqDsgw6K4RQ7FKrIoXuFPMYocilVkUbwik+IWWRSvyHHWxUo1jkRERERERERExC+NOBIREREREREREb+UOBpDjDGFxpi/GmN2GmO2G2O+5LRnGGNWGmN2O/+mO+2lxpj3jTEdxpivnnKsrzjH2GaMedYYE9/POe9yjrvbGHOX05ZsjPnQZztmjPmvM339kSpc4ua0326M2eIc4wdn8rojUYhi9YoxpsEY89Ip7f9ojNljjLHGmKwzdc2RLMjx+pITq+3GmC8PcM7lxpgyJzZf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\n",
      "text/plain": [
       "<Figure size 1440x720 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "sp_cumprod = strategy_profit['cumprod_profit']\n",
    "p_hs300 = price.loc[test_start_date:test_end_date]['close']\n",
    "#p_hs300 = get_price(select_index,start_date=test_start_date,end_date=test_end_date,fields=['close'])\n",
    "fig = plt.figure(figsize=(20,10))\n",
    "ax0 = fig.add_subplot(2,1,1)\n",
    "ax1 = fig.add_subplot(2,1,2)\n",
    "ax0.plot(sp_cumprod)\n",
    "ax1.plot(p_hs300)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>signal</th>\n",
       "      <th>profit</th>\n",
       "      <th>selct_profit</th>\n",
       "      <th>cumprod_profit</th>\n",
       "      <th>cumsum_profit</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2018-06</th>\n",
       "      <td>0</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2018-07</th>\n",
       "      <td>0</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2018-08</th>\n",
       "      <td>0</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2018-09</th>\n",
       "      <td>0</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2018-10</th>\n",
       "      <td>0</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2018-11</th>\n",
       "      <td>0</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2018-12</th>\n",
       "      <td>0</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-01</th>\n",
       "      <td>0</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>1.000000</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-02</th>\n",
       "      <td>1</td>\n",
       "      <td>0.059797</td>\n",
       "      <td>0.059797</td>\n",
       "      <td>1.059797</td>\n",
       "      <td>0.059797</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-03</th>\n",
       "      <td>1</td>\n",
       "      <td>-0.072802</td>\n",
       "      <td>-0.072802</td>\n",
       "      <td>0.982641</td>\n",
       "      <td>-0.013005</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-04</th>\n",
       "      <td>0</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.982641</td>\n",
       "      <td>-0.013005</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-05</th>\n",
       "      <td>0</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.982641</td>\n",
       "      <td>-0.013005</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-06</th>\n",
       "      <td>0</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.982641</td>\n",
       "      <td>-0.013005</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-07</th>\n",
       "      <td>1</td>\n",
       "      <td>0.011792</td>\n",
       "      <td>0.011792</td>\n",
       "      <td>0.994228</td>\n",
       "      <td>-0.001213</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-08</th>\n",
       "      <td>1</td>\n",
       "      <td>-0.002765</td>\n",
       "      <td>-0.002765</td>\n",
       "      <td>0.991480</td>\n",
       "      <td>-0.003978</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-09</th>\n",
       "      <td>1</td>\n",
       "      <td>0.029890</td>\n",
       "      <td>0.029890</td>\n",
       "      <td>1.021115</td>\n",
       "      <td>0.025912</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-10</th>\n",
       "      <td>1</td>\n",
       "      <td>-0.029433</td>\n",
       "      <td>-0.029433</td>\n",
       "      <td>0.991061</td>\n",
       "      <td>-0.003521</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-11</th>\n",
       "      <td>1</td>\n",
       "      <td>0.082423</td>\n",
       "      <td>0.082423</td>\n",
       "      <td>1.072747</td>\n",
       "      <td>0.078902</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2019-12</th>\n",
       "      <td>1</td>\n",
       "      <td>-0.111718</td>\n",
       "      <td>-0.111718</td>\n",
       "      <td>0.952902</td>\n",
       "      <td>-0.032816</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         signal    profit  selct_profit  cumprod_profit  cumsum_profit\n",
       "2018-06       0  0.000000      0.000000        1.000000       0.000000\n",
       "2018-07       0  0.000000      0.000000        1.000000       0.000000\n",
       "2018-08       0  0.000000      0.000000        1.000000       0.000000\n",
       "2018-09       0  0.000000      0.000000        1.000000       0.000000\n",
       "2018-10       0  0.000000      0.000000        1.000000       0.000000\n",
       "2018-11       0  0.000000      0.000000        1.000000       0.000000\n",
       "2018-12       0  0.000000      0.000000        1.000000       0.000000\n",
       "2019-01       0  0.000000      0.000000        1.000000       0.000000\n",
       "2019-02       1  0.059797      0.059797        1.059797       0.059797\n",
       "2019-03       1 -0.072802     -0.072802        0.982641      -0.013005\n",
       "2019-04       0  0.000000      0.000000        0.982641      -0.013005\n",
       "2019-05       0  0.000000      0.000000        0.982641      -0.013005\n",
       "2019-06       0  0.000000      0.000000        0.982641      -0.013005\n",
       "2019-07       1  0.011792      0.011792        0.994228      -0.001213\n",
       "2019-08       1 -0.002765     -0.002765        0.991480      -0.003978\n",
       "2019-09       1  0.029890      0.029890        1.021115       0.025912\n",
       "2019-10       1 -0.029433     -0.029433        0.991061      -0.003521\n",
       "2019-11       1  0.082423      0.082423        1.072747       0.078902\n",
       "2019-12       1 -0.111718     -0.111718        0.952902      -0.032816"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "strategy_profit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sp_cumprod = strategy_profit['cumprod_profit']\n",
    "p_hs300 = price.loc[test_start_date:test_end_date]['close']\n",
    "#p_hs300 = get_price(select_index,start_date=test_start_date,end_date=test_end_date,fields=['close'])\n",
    "fig = plt.figure(figsize=(20,10))\n",
    "ax0 = fig.add_subplot(2,1,1)\n",
    "ax1 = fig.add_subplot(2,1,2)\n",
    "ax0.plot(sp_cumprod)\n",
    "ax1.plot(p_hs300)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:py35]",
   "language": "python",
   "name": "conda-env-py35-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
